正确理解HibernateInverse

通过Hibernate Inverse的设置来决定是由谁来维护表和表之间的关系。最近有朋友问我Hibernate关于多对多关于删除中间表数据的问题,关键是Inverse的设置,下面引用网友的一篇文章。

创新互联公司-专业网站定制、快速模板网站建设、高性价比垫江网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式垫江网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖垫江地区。费用合理售后完善,十载实体公司更值得信赖。

Inverse是Hibernate双向关系中的基本概念,当然对于多数实体,我们并不需要双向关联,更多的可能会选择单向关联,况且我们大多数人 一般采用一对多关系,而一对多双向关联的另一端:多对一的Inverse属性是不存在,其实它默认就是Inverse=false.从而防止了在一对多端 胡乱设置Inverse也不至于出错。但是Inverse设置不当确实会带来很大的性能影响,这点是我们必须关注的。

这篇文章已经详细分析了Hibernate Inverse设置不当带来的影响:http://www.Hibernate.org/155.html,看了这篇文章,还是很有必要再写下一些总结的:

1)Hibernate Inverse中提及的side其实是指一个类或者表的概念,双向关联其实是指双方都可以取得对方的应用。

2)维护关系这个名词还是稍显模糊或者晦涩。我们一般说A类或者A表(这里的表的是指多对多的连接表)有责任维护关系,其实这里的意思是说,我在应 用在更新,创建,删除(读就不用说了,双向引用正是为了方便读而出现)A类或者A表时,此时创建的SQL语句必须有责任保证关系的正确修改。

3)Inverse=false的side(side其实是指Inverse=false所位于的class元素)端有责任维护关系,而Inverse=true端无须维护这些关系。

4)我们说Hibernate Inverse设立不当会导致性能低下,其实是说Inverse设立不当,会产生多余重复的SQL语句甚至致使JDBC exception的throw。这是我们在建立实体类关系时必须需要关注的地方。一般来说,Inverse=true是推荐使用,双向关联中双方都设置 Inverse=false的话,必会导致双方都重复更新同一个关系。但是如果双方都设立Inverse=true的话,双方都不维护关系的更新,这也是 不行的,好在一对多中的一端:many-to-one默认是Inverse=false,避免了这种错误的产生。但是多对多就没有这个默认设置了,所以很 多人经常在多对多的两端都使用Inverse=true,结果导致连接表的数据根本没有记录,就是因为他们双分都没有责任维护关系。所以说,双向关联中***的设置是一端为Inverse=true,一端为Inverse=false。一般Inverse=false会放在多的一端,那么有人提问了, many-to-many两边都是多的,Inverse到底放在哪儿?其实Hibernate建立多对多关系也是将他们分离成两个一对多关系,中间连接一 个连接表。所以通用存在一对多的关系,也可以这样说:一对多是多对多的基本组成部分。

看下面的多对多的定义大家更会清楚”多对多“与“一对多”的关系:其中我们注意标签的特点就知道,它是定义了一个多对多关系,而不是

 
 
 
  1.    
  2. "-//Hibernate/Hibernate Mapping DTD 2.0//EN"   
  3. "http://Hibernate.sourceforge.net/Hibernate-mapping-2.0.dtd">   
  4.    
  5. dynamic-update="true" dynamic-insert="true" >  
  6.       
  7.        
  8.        
  9.      
  10.    
  11.     update="true" insert="true" column="name" />  
  12.       
  13.        
  14.        
  15.      
  16.    
  17. dynamic-update="true" dynamic-insert="true" >  
  18.       
  19.        
  20.        
  21.      
  22.  
  23.    
  24.    insert="true" column="name" />  
  25.  
  26.       
  27.        
  28.        
  29.      
  30.    
  31.  

在对多对中,因为一端维护关系另一端不维护关系的原因,我们必须注意避免在应用中用不维护关系的类建立关系,因为这样建立的关系是不会在数据库中存储的。基于上面的映射文件代码给出一个例子:

 
 
 
  1. package org.Hibernate.auction;   
  2. import java.util.*;  
  3. /**   
  4. * @author Administrator   
  5.  
  6. * To change the template for this generated type comment go to   
  7. * Window>Preferences>Java>Code Generation>Code and Comments   
  8. */   
  9. public class TestA {   
  10. int id;   
  11. String name;   
  12. Set testBs=new HashSet();   
  13. public TestA(){   
  14. }   
  15. public TestA(int id){   
  16.    setId(id);   
  17. }   
  18. public int getId(){   
  19.    return id;   
  20. }   
  21. public void setId(int id){   
  22.    this.id=id;   
  23. }   
  24. public String getName(){   
  25.    return name;   
  26. }   
  27. public void setName(String name){   
  28.    this.name=name;   
  29. }   
  30. public Set getTestBs(){   
  31.    return testBs;   
  32. }   
  33. public void setTestBs(Set s){   
  34.    testBs=s;   
  35. }   
  36. public void addTestB(TestB tb){   
  37.    testBs.add(tb);   
  38. }public static void main(String[] args) {   
  39. }   
  40. }  
  41. public class TestB {  
  42. int id;   
  43. String name;   
  44. Set testAs=new HashSet();   
  45. public TestB(){   
  46. }   
  47. public TestB(int id){   
  48.    setId(id);   
  49. }   
  50. public int getId(){   
  51.    return id;   
  52. }   
  53. public void setId(int id){   
  54.    this.id=id;   
  55. }   
  56. public String getName(){   
  57.    return name;   
  58. }   
  59. public void setName(String name){   
  60.    this.name=name;   
  61. }   
  62. public Set getTestAs(){   
  63.    return testAs;   
  64. }   
  65. public void setTestAs(Set s){   
  66.    testAs=s;   
  67. }   
  68. public void addTestA(TestA ta){   
  69.    testAs.add(ta);   
  70. }   
  71. public static void main(String[] args) {   
  72. }   

测试代码:

 
 
 
  1. public void doTest() throws Exception{   
  2.    TestA a1=new TestA(1);   
  3.    TestA a2=new TestA(2);   
  4.    TestA a3=new TestA(3);   
  5.    TestB b1=new TestB(1);   
  6.    TestB b2=new TestB(2);   
  7.    TestB b3=new TestB(3);   
  8.    a1.addTestB(b1);   
  9.    a1.addTestB(b2);   
  10.    a1.addTestB(b3);   
  11.    b2.addTestA(a1);   
  12.    b2.addTestA(a2);   
  13.    Session s = factory.openSession();   
  14.    s = factory.openSession();   
  15.    Session session = factory.openSession();   
  16. session.save(a1);   
  17. session.flush();   
  18. session.close();  

测试后连接表的数据为:

testa              testb

1                  1

1                  2

1                  3

根据Inverse规则,对这些代码:b2.addTestA(a1);   b2.addTestA(a2); 建立的关系,数据库并没有存储下来,因为TestB没有责任维护这些关系,所以产生的sql语句自然不会有针对Testa_testB表的操作了。假设应 用中真的需要这些方法,那么我们可以修改TestB的方法,让他们注意在维护端类中执行相应的操作以使得关系能够在数据库中保存下来,更改TestB如 下:

 
 
 
  1. /*   
  2. * Created on 2004-7-25   
  3.  
  4. * To change the template for this generated file go to   
  5. * Window>Preferences>Java>Code Generation>Code and Comments   
  6. */   
  7. package org.Hibernate.auction;   
  8. import java.util.*;  
  9. /**   
  10. * @author Administrator   
  11.  
  12. * To change the template for this generated type comment go to   
  13. * Window>Preferences>Java>Code Generation>Code and Comments   
  14. */   
  15. public class TestB {  
  16. int id;   
  17. String name;   
  18. Set testAs=new HashSet();   
  19. public TestB(){   
  20. }   
  21. public TestB(int id){   
  22.    setId(id);   
  23. }   
  24. public int getId(){   
  25.    return id;   
  26. }   
  27. public void setId(int id){   
  28.    this.id=id;   
  29. }   
  30. public String getName(){   
  31.    return name;   
  32. }   
  33. public void setName(String name){   
  34.    this.name=name;   
  35. }   
  36. public Set getTestAs(){   
  37.    return testAs;   
  38. }   
  39. public void setTestAs(Set s){   
  40.    testAs=s;   
  41. }   
  42. public void addTestA(TestA ta){   
  43.    testAs.add(ta);   
  44.    ta.addTestB(this);   
  45. }   
  46. public static void main(String[] args) {   
  47. }   
  48. }  

那么测试执行后连接表的数据为:

testa          testb

1               2

1               3

1               1

2               2

测试通过。

【编辑推荐】

  1. 强人Hibernate文档笔记(上)
  2. 强人Hibernate文档笔记(中)
  3. 强人Hibernate文档笔记(下)
  4. Hibernate一对多关系的处理
  5. Hibernate的性能优化

分享标题:正确理解HibernateInverse
分享URL:http://www.hantingmc.com/qtweb/news27/488827.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联