总是在您的集合变量中输入inverse =“ true”吗?
许多Hibernate文章试图用许多Hibernate“官方”行话来解释“逆向”,这是很难理解的(至少对我而言)。 他们甚至在几篇文章中建议不要理会什么是“逆”,而总是将inverse =“ true”放入集合变量中。该陈述始终是正确的–“在集合变量中放入inverse = true”,但不要蒙上阴影,请尝试理解背后的原因对于优化Hibernate性能至关重要。
什么是“逆”?
这是Hibernate中最令人困惑的关键字,至少我花了很长时间了解它。 “ inverse ”关键字始终以一对多和多对多关系声明(多对一没有inverse关键字),这意味着由哪一方负责处理该关系。
“反向”,应该改为“关系所有者”吗?
在Hibernate中,只有“关系所有者”应该维护该关系,并且创建“ inverse”关键字来定义维护关系的所有者是哪一方。 但是,“ inverse”关键字本身不够详细,我建议将关键字更改为“ Relationship_owner ”。
简而言之,inverse =“ true”表示这是关系所有者,而inverse =“ false”(默认)表示不是关系所有者。
1.一对多关系
这是一对多关系表的设计,一个STOCK表在STOCK_DAILY_RECORD表中有很多出现。
2.休眠实现
请参见XML映射文件中的Hibernate实现。
文件:Stock.java
public class Stock implements java.io.Serializable {
...
private Set<StockDailyRecord> stockDailyRecords =
new HashSet<StockDailyRecord>(0);
...
文件:StockDailyRecord.java
public class StockDailyRecord implements java.io.Serializable {
...
private Stock stock;
...
档案: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>
...
文件: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.逆=真/假
反向关键字应用于一对多关系。 这是一个问题,如果在“ Stock”对象中执行保存或更新操作,是否应该更新“ stockDailyRecords”关系?
档案: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.逆=“真”
如果set变量中的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将生成三个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
(?, ?, ?, ?, ?, ?)
Hibernate:
update
mkyongdb.stock_daily_record
set
STOCK_ID=?
where
RECORD_ID=?
Stock将通过Set变量(stockDailyRecords)更新“ stock_daily_record.STOCK_ID ”,因为Stock是关系所有者。
注意
第三句话实际上是没有必要的。
更新示例…
更新“ Stock”对象时,Hibernate将生成两个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=?
注意
同样,第三条语句不是必需的。
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将生成两个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
(?, ?, ?, ?, ?, ?)
更新示例…
当“股票”对象更新时,Hibernate将生成一个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代码至关重要,它有助于避免许多不必要的更新语句,例如上面的“为inverse = false插入和更新示例”。 最后,请记住inverse =“ true”,这意味着这是处理该关系的关系所有者。
参考
- http://simoes.org/docs/hibernate-2.1/155.html
- http://docs.jboss.org/hibernate/stable/core/reference/en/html/example-parentchild.html
- http://tadtech.blogspot.com/2007/02/hibernate-when-is-inversetrue-and-when.html
翻译自: https://mkyong.com/hibernate/inverse-true-example-and-explanation/