舒适达牙膏有效果吗:配置文件中inverse属性对于父子关系维护的影响

来源:百度文库 编辑:九乡新闻网 时间:2024/04/28 04:40:38
配置文件中inverse属性对于父子关系维护的影响2009-06-02 16:50

hibernate的model配置文件如下:
       
           
       
      
       
           
               
           

           
       

其中的inverse="true"表示 ParentPO 本身不维护表之间的关系,而由相反的一方 child来维护, CASCADE=“ALL”表示 无论是update,insert ,delete 都保持级连关系
lazy="true"表示初始化父亲的时候不会把所有的儿子都从数据库中load进来。

首先讲讲inverse=true作用: 这里关系是由儿子维护的,所以如果只是往父亲里加入儿子,不给儿子设置父亲的话session.save(parent),就不会保存儿子! 看这个例子:

  1.                 ChildPO child = new ChildPO();,
  2.                  ITxMgr tx = null;   
  3.                  tx = HibernateTxMgr.beginTrans("Add a new relationships...");;   
  4.                  session = (Session); tx.getSession();;   
  5.                  parent = new ParentPO();;   
  6.                  ChildPO child = new ChildPO();;   
  7.                  ChildPO child2 = new ChildPO();;   
  8.                  List list = new ArrayList();;   
  9.                  list.add(child);;   
  10.                  list.add(child2);;   
  11.                  parent.setChildren(list);;   
  12.                  session.save(parent);;   
  13.                  session.flush();;   
  14.                  System.out.println("dddddddddddddddddddddddddddddddddddddddddddddddddddddd"); ;   
  15.                  ChildPO child3 = new ChildPO();;   
  16.                  child3.setParent(parent);;   
  17.                  session.save(child3);;   
  18.                  session.flush();;   
  19.                  System.out.println("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); ;   
  20.                  tx.endTrans();;   
生成的SQL没有变

Java代码
  1. Hibernate: insert into PARENT (ID); values (default);   
  2.   
  3. Hibernate: insert into CHILD (PARENTID, ID); values (?, default);   
  4.   
  5. Hibernate: insert into CHILD (PARENTID, ID); values (?, default);   
  6.   
  7. dddddddddddddddddddddddddddddddddddddddddddddddddddddd   
  8. Hibernate: insert into CHILD (PARENTID, ID); values (?, default);   
  9. eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee   
数据库中数据如下:(注意父子关系丢失了)
    ID           PARENTID   
  1. ----------- -----------   
  2.          74            -   
  3.          75            -   
  4.          76          45   
  5. C:\Myapp\SQLLIB\BIN>db2 select * from parent   
  6.   
  7. ID   
  8. -----------   
  9.          45   

为什么最后一个孩子的父亲没有丢失呢? 就在于child3.setParent(parent),因为关系是由孩子维护的,如果child不setParent,或者 new childPO(父亲)的话 父子关系就丢失了,parent.setChildren(list)是没有用的!

之所以用inverse=true是为了提高系统的性能,在没有设置inverse=true的情况下同样调用上面的代码则生成的sql如下:

  1. Hibernate: insert into CHILD (PARENTID, ID); values (?, default);   
  2.   
  3. Hibernate: insert into CHILD (PARENTID, ID); values (?, default);   
  4.   
  5. Hibernate: update CHILD set PARENTID=? where ID=?   
  6. dddddddddddddddddddddddddddddddddddddddddddddddddddddd   
  7. Hibernate: insert into CHILD (PARENTID, ID); values (?, default);   
  8. Hibernate: values IDENTITY_VAL_LOCAL();   

    此时系统明显比原来多了一句Hibernate: update CHILD set PARENTID=? where ID=?针对每一个孩子都去更新父亲的id明显速度很慢,因为父亲有个孩子的集合,他无法知道哪个孩子的父亲id已经指向自己了,所以对于每一个孩子,都要更新父亲id,而这个关系由孩子维护就好多了,每个孩子只有一个父亲,只有设置过的才需要更新,所以显然,这个父子关系由孩子来维护比较省力.减轻了数据库的负担。

在没有 inverse=true 的情况下,父子两边都维护父子关系所以 只要有 parent.setchildren(),或者 child.setparent()两者之一就可以了

inverse=true的总结:不用inverse=ture,对开发者来说写代码比较方便,但是程序执行的效率比较低下,,用inverse=ture一定要注意,一定要对维护关系的一方进行调用,否则会有意想不到的破坏力。