zoukankan      html  css  js  c++  java
  • Hibernate inverse用法(转载)

    出处:http://blog.csdn.net/xiaoxian8023/article/details/15380529

            一、Inverse是hibernate双向关系中的基本概念。inverse的真正作用就是指定由哪一方来维护之间的关联关系。当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之间的关联关系,说白了就是hibernate如何生成Sql来维护关联的记录! 

           Hibernate仅仅按照主控方对象的状态的变化来同步更新数据库。按照原来的映射文件,people.getAddresses().add(address),即主控方对象的状态发生了改变,因此数据库会跟着对象状态的变化来同步更新数据库;而address.setPeople(people),即被控方对象的状态发生了改变,它是不能触发对象和数据库的同步更新的。

          (实例1):

           举个最简单的一对多父子关系。那么代码就写成:

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. Parent p = new Parent();  
    2. Child c = new Child();  
    3. c.setParent(p);  //维护父子之间关系  
    4. p.getChildren().add(c);  
    5.   
    6. session.save(p);  
    7. session.flush();  

           映射文件配置:

    [html] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. 父亲中的关系映射  
    2. {set name="children" lazy="true" inverse="true"}  
    3.       {key column="parent_id"/}  
    4.       {one-to-many class="test.Child"/}  
    5. {/set}  
    6.   
    7. 儿子中关系映射  
    8. {many-to-one name="parent" column="parent_id" not-null="true"/}  

           set中inverse="true",说明父子关系只在多的一端(Child)维护。所以只会发出2个insert语句。

           注意:{many-to-one}总是设成“inverse=false”的,而且这个属性在Mapping中是不存在的!

           这样运行的下来的结果就是:

    [sql] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. Hibernate: insert into parent (id) values (?)  
    2. Hibernate: insert into child (parent_id, id) values (?, ?)  

           如果将set中的inverse设为true,那么会发出3条sql语句,前2条是insert语句,后1条是update语句用来维护parent和child类的父子关系。

           当然,假如c.setParent(p)注释掉(破坏了父子关系),结果就变成了:

    [sql] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. Hibernate: insert into parent (id) values (?)  

    ===================================================
         (实例2):
           一个Person可以参加多个Event,一个Event有多个Person参加。映射文件如下:

    [html] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. <!-- Person.hbm.xml -->  
    2. <hibernate-mapping package="events">  
    3.   <class name="Person" table="person">  
    4.       <id name="id" column="person_id">  
    5.           <generator class="native"/>  
    6.       </id>  
    7.       <property name="age" length="0"/>  
    8.       <property name="firstname"/>  
    9.       <property name="lastname"/>  
    10.       <set name="events" table="person_event">  
    11.           <key column="person_id"/>  
    12.           <many-to-many column="event_id" class="events.Event"/>  
    13.       </set>  
    14.   </class>  
    15. </hibernate-mapping>  
    16.   
    17. <!-- Event.hbm.xml -->  
    18. <hibernate-mapping>  
    19.   <class name="events.Event" table="events">  
    20.       <id name="id" column="event_id">  
    21.             <generator class="native"/>  
    22.       </id>  
    23.       <property name="date" column="events_date" type="timestamp"/>  
    24.       <property name="title" column="events_title"/>  
    25.       <set name="participants" table="person_event" inverse="true">  
    26.           <key column="event_id"/>  
    27.           <many-to-many column="person_id" class="events.Person"/>  
    28.       </set>  
    29.   </class>  
    30. </hibernate-mapping>  


           inverse=true的含义: 由双向关联另一方维护该关联,己方不维护该关联(只能进行查询操作)。在上述代码中,由Person方维护该<many-to-many>关系,示例代码如下(以向Person参与的Event中加入新的Event为例):
           

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. Session session = HibernateUtil.getSessionFactory().getCurrentSession();  
    2.        session.beginTransaction();  
    3.        Person p = (Person) session.load(Person.class, personId);  
    4.        Event e = (Event) session.load(Event.class, eventId);  
    5.        p.getEvents().add(e);//执行该代码时,hibernate会向中间表 person_event中插入person_id和event_id记录,如果换成e.getParticipants().add(p)的话,该代码将不会被执行,即hibernate不会向表person_event中插入记录。  
    6.        session.getTransaction().commit();  


           要注意的一点:在双向关联的关系中,映射的column(和table)的值要一致(即要用相同的表名和列名),不然设置为inverse="true"的这方将失去这个双向关系,而变成了一个单向关联。

           二、Inverse和Cascade的比较

           Inverse:负责控制关系,默认为false,也就是关系的两端都能控制,但这样会造成一些问题,更新的时候会因为两端都控制关系,于是重复更新。一般来说有一端要设为true。

           Cascade:负责控制关联对象的级联操作,包括更新、删除等,也就是说对一个对象进行更新、删除时,其它对象也受影响,比如我删除一个对象,那么跟它是多对一关系的对象也全部被删除。
    举例说明区别:删除“一”那一端一个对象O的时候,如果“多”的那一端的Inverse设为true,则把“多”的那一端所有与O相关联的对象外键清空;如果“多”的那一端的Cascade设为Delete,则把“多”的那一端所有与O相关联的对象全部删除。

  • 相关阅读:
    Chrome cookies folder
    Fat URLs Client Identification
    User Login Client Identification
    Client IP Address Client Identification
    HTTP Headers Client Identification
    The Personal Touch Client Identification 个性化接触 客户识别
    购物车 cookie session
    购物车删除商品,总价变化 innerHTML = ''并没有删除节点,内容仍存在
    453
    购物车-删除单行商品-HTMLTableElement.deleteRow()
  • 原文地址:https://www.cnblogs.com/rixiang/p/5377550.html
Copyright © 2011-2022 走看看