hibernate inverse使用释疑
来源:互联网 发布:余额宝优化理财怎么样 编辑:程序博客网 时间:2024/06/05 02:25
总是令你的集合变量在配置文件中对应的映射元素的Inverse=true吗?
有许多hibernate的文章尝试用hibernate的官方术语来解释“inverse”,但是这很难理解(至少对我来说)。有少数文章甚至建议读者不去理会Inverse的含义,只要记住令集合变量在配置文件中对应的映射元素的inverse属性为true.
“令集合变量在配置文件中对应的映射元素的inverse属性为true.”的说法也不能说它是错的,但是不要让它影响你去发现inverse的精华所在,尝试着去发现它优化hibernate执行效率的精华吧。
inverse的作用是什么?
inverse是Hibernate中最令人困惑的关键字,至少我用了很长时间才弄清它的作用和使用方法。"inverse"关键字在一对多关系和多对多关系中被声明使用(在多对一中没有inverse关键字)。它的取值决定了具有关联关系(一对多或多对多)的两个实体类哪一个负责维护二者之间的关系。
"inverse",应该改成“relationship owner"吗?
然而“inverse”关键字生涩难懂,我建议将它改为“relationship_owner”
总之,inverse="true"说明当前配置文件对应的实体类不是关系的拥有者,而其对应的关联实体类是关系的拥有者(也就是inverse属性所在元素对应的集合变量引用的实体类为关系的拥有者),反之相反。
1.一对多关系
2.hibernate的实现
hibernate xml映射文件的实现
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
下面展示了inverse 关键字在一对多关系上的应用。这里有一个问题,如果对“Stock”对象进行save或者update操作,“Stock”对象应该更新“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”
如果在set元素中有inverse="true",它说明“stock_daily_record”是关系的拥有者,那么Stock将不能维护它与stock_daily_record对应的实体类对象间的关联关系。
<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将维护它与stock_daily_record对应的实体类对象间的关联关系。
<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”是关系的拥有者。
insert的例子
当一个“Stock”对象被保存,hiberante将生成三个sql语句,两个insert语句一个update语句。
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将通过stockDailyRecords变量来更新“stock_daily_record.STOCK_ID”,因为在这里Stock是关系的拥有者。
第三个sql语句是多余的
Update 例子 …
当一个“Stock”对象被更新,hibernate将生成两个sql语句,一个insert语句和一个update
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”(也就是StockDailyRecord实体类) 是关系的拥有者,“stock”将不能维护二者之间的关联关系。
Insert 例子 …
当一个“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 (?, ?, ?, ?, ?, ?)
Update 例子…
当一个“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 (?, ?, ?, ?, ?, ?)
许多人喜欢拿inverse和cascade进行比较,但是它们是两个完全不同的概念,二者不同请浏览differential here
总结
理解Inverse的本质含义是为了优化你的hibernate代码,它可以避免许多不必要的update语句,如上述的“inverset=ture下的insert 与update的例子”。
最后记住:inverse=“true”告诉hibernate具有关联关系的两个实体类哪一个是维护二者关系的关系拥有者。
原文:http://www.mkyong.com/hibernate/inverse-true-example-and-explanation/
个人阅读后对inverse=true的理解:
inverse=true应该从数据库表来看(当然这有点违反了hibernate的设计初衷了),即哪个表是外键所在的表,那么这个表
对应的实体类就应该是“关系的拥有者”,进而这个实体类对应的关联实体类的xml 映射文件就应该采用inverse=true.
- hibernate inverse使用释疑
- Hibernate中inverse的使用
- Hibernate-inverse
- Hibernate inverse
- hibernate inverse
- hibernate----inverse
- hibernate inverse
- hibernate inverse
- hibernate inverse
- Hibernate inverse
- hibernate inverse
- hibernate中cascade和inverse的使用
- Hibernate之inverse与cascade的使用
- Hibernate中cascade和inverse的使用
- hibernate映射中inverse属性的使用
- hibernate中inverse=true的使用
- hibernate中cascade和inverse的使用
- Hibernate之inverse与cascade的使用(2)
- 创建DLL文件,封装窗体的实现方法实例
- .net c# mvc模式中
- Ubuntu下安装Apache+PHP+Mysql
- 写DLL引起与主程序资源冲突的解决方法
- xmmap file for mindmanager and thinking space.(mindmap)
- hibernate inverse使用释疑
- Silverlight 通过反射创建WCF通信
- jpeg 标志
- 一次性提出WORD里面所有的照片
- android 逐帧动画自动播放以及逐帧动画与渐变动画结合的停止问题
- AndroidGUI25:定制Activity的标题栏(Titlebar)
- 木条加工
- JPEG exif
- 为什么我们同时搞acm,结果是你就可以去final