inverse = “true”例と解説
このステートメントは常にtrueです。 “コレクション変数にput inverse = true”を設定しますが、目立たないようにしてください。理由は、Hibernateのパフォーマンスを最適化するために不可欠です。
「逆」とは何ですか?
これはHibernateの中で最も混乱するキーワードですが、少なくとも私はそれを理解するのにかなり長い時間がかかりました。 ”
inverse
“キーワードは常にone-to-many
と
many-to-many ** の関係で宣言されます(many-to-oneはinverseキーワードを持たない)。その関係の
“inverse”は “relationship owner”に変更する必要がありますか?
Hibernateでは、「関係所有者」だけが関係を維持する必要があり、「inverse」キーワードは、関係を維持する所有者のどちら側を定義するために作成されます。しかし、 “逆”キーワード自体は冗長ではないので、キーワードを ”
relationship__owner
“に変更することをお勧めします。
要するに、inverse = “true”はこれが関係所有者であることを意味し、inverse = “false”(デフォルト)はそれがそうでないことを意味します。
1. 1対多の関係
これは
1対多
関係表の設計であり、STOCK表にはSTOCK
DAILY
RECORD表に多数のオカレンスがあります。
2.ハイバネーションの実装
XMLマッピングファイルのHibernate実装を参照してください。
File:Stock.java
public class Stock implements java.io.Serializable { ... private Set<StockDailyRecord> stockDailyRecords = new HashSet<StockDailyRecord>(0); ...
File:StockDailyRecord.java
public class StockDailyRecord implements java.io.Serializable { ... private Stock stock; ...
File:Stock.hbm.xml
<hibernate-mapping> <class name="com.mkyong.common.Stock" table="stock" ...> ... <set name="stockDailyRecords" table="stock__daily__record" fetch="select"> <key> <column name="STOCK__ID" not-null="true"/> </key> <one-to-many class="com.mkyong.common.StockDailyRecord"/> </set> ...
File:StockDailyRecord.hbm.xml
<hibernate-mapping> <class name="com.mkyong.common.StockDailyRecord" table="stock__daily__record" ...> ... <many-to-one name="stock" class="com.mkyong.common.Stock"> <column name="STOCK__ID" not-null="true"/> </many-to-one> ...
3. inverse = true/false
逆キーワードは、1対多の関係で適用されます。これは、 “stockDailyRecords”関係を更新する必要がありますか?
File:Stock.hbm.xml
<class name="com.mkyong.common.Stock" table="stock" ...> ... <set name="stockDailyRecords" table="stock__daily__record" inverse="{true/false}" fetch="select"> <key> <column name="STOCK__ID" not-null="true"/> </key> <one-to-many class="com.mkyong.common.StockDailyRecord"/> </set> ...
-
1。 inverse = “true” **
セット変数のinverse = “true”の場合、 “stock
daily
record”はリレーションシップ所有者なので、Stockはリレーションシップを更新しません。
<class name="com.mkyong.common.Stock" table="stock" ...> ... <set name="stockDailyRecords" table="stock__daily__record" inverse="true" >
-
2。 inverse = “false” **
set変数のinverse = “false”(デフォルト)の場合は、 “stock”がリレーション所有者であり、Stockがリレーションシップを更新することを意味します。
<class name="com.mkyong.common.Stock" table="stock" ...> ... <set name="stockDailyRecords" table="stock__daily__record" inverse="false" >
以下の例をご覧ください:
4. inverse = “false”例
キーワード “inverse”が定義されていない場合、inverse = “false”が使用されます。
<!--Stock.hbm.xml--> <class name="com.mkyong.common.Stock" table="stock" ...> ... <set name="stockDailyRecords" table="stock__daily__record" inverse="false">
それは、 “株”が関係の所有者であり、それが関係を維持することを意味します。
-
例を挿入する… **
“Stock”オブジェクトが保存されると、Hibernateは3つのSQL文、2つの挿入、1つの更新を生成します。
session.beginTransaction(); Stock stock = new Stock(); stock.setStockCode("7052"); stock.setStockName("PADINI"); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock); session.save(stockDailyRecords); session.getTransaction().commit();
出力…
Hibernate: insert into mkyongdb.stock (STOCK__CODE, STOCK__NAME) values (?, ?) Hibernate: insert into mkyongdb.stock__daily__record (STOCK__ID, PRICE__OPEN, PRICE__CLOSE, PRICE__CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?) Hibernate: update mkyongdb.stock__daily__record set STOCK__ID=? where RECORD__ID=?
ストックはリレーションシップ所有者であるため、 ”
stock
daily
record.STOCK__ID
“をSet変数(stockDailyRecords)を使用して更新します。
-
注** 3番目のステートメントは実際には必要ありません。
-
アップデート例… **
“Stock”オブジェクトが更新されると、Hibernateは挿入と更新の2つのSQL文を生成します。
session.beginTransaction(); Stock stock = (Stock)session.get(Stock.class, 57); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stockDailyRecords); session.update(stock); session.getTransaction().commit();
出力…
Hibernate: insert into mkyongdb.stock__daily__record (STOCK__ID, PRICE__OPEN, PRICE__CLOSE, PRICE__CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?) Hibernate: update mkyongdb.stock__daily__record set STOCK__ID=? where RECORD__ID=?
-
注意** もう一度、3番目のステートメントは必要ありません。
5. inverse = “true”例
キーワード “inverse = true”が定義されている場合:
<!--Stock.hbm.xml--> <class name="com.mkyong.common.Stock" table="stock" ...> ... <set name="stockDailyRecords" table="stock__daily__record" inverse="true">
さて、 ”
stockDailyRecords
“は関係所有者であり、 “stock”はその関係を維持しないことを意味します。
-
例を挿入する… **
“Stock”オブジェクトが保存されると、Hibernateは2つのSQL挿入ステートメントを生成します。
session.beginTransaction(); Stock stock = new Stock(); stock.setStockCode("7052"); stock.setStockName("PADINI"); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock); session.save(stockDailyRecords); session.getTransaction().commit();
__出力…
Hibernate: insert into mkyongdb.stock (STOCK__CODE, STOCK__NAME) values (?, ?) Hibernate: insert into mkyongdb.stock__daily__record (STOCK__ID, PRICE__OPEN, PRICE__CLOSE, PRICE__CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?)
-
アップデート例… **
“Stock”オブジェクトが更新されると、Hibernateは1つのSQL文を生成します。
session.beginTransaction(); Stock stock = (Stock)session.get(Stock.class, 57); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stockDailyRecords); session.update(stock); session.getTransaction().commit();
出力…
Hibernate: insert into mkyongdb.stock__daily__record (STOCK__ID, PRICE__OPEN, PRICE__CLOSE, PRICE__CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?)
-
inverse vs cascade ** 逆数とカスケードを比較するのが好きですが、どちらも全く異なる概念です。
結論
あなたのHibernateコードを最適化するためには “inverse”を理解することが不可欠です。上記の “inverse = falseの挿入と更新の例”のような多くの不要な更新文を避けるのに役立ちます。最後に、inverse = “true”を覚えてみてください。これは、関係を処理する関係所有者であることを意味します。