• 级联关系(内容大部分来自JavaEE轻量型解决方案其余的是我的想法)


    1. 级联关系

    在Hibernate程序中持久化的对象之间会通过关联关系互相引用。对象进行保存、更新和删除等操作时,有时需要被关联的对象也执行相应的操作,如:假设需要关联关系的主动方对象执行操作时,被关联的对象也会同步执行同一操作。这一问题可以通过使用Hibernate的级联(cascade)功能来解决。

    例如:当试图删除顾客对象时,通过级联关系让Hibernate决定是否删除该对象对应的所有订单对象。
    cascade是<set>元素的一个属性,该属性常用值及描述如下表:
     属性值    描述 
     none                    默认值,表示关联对象之间无级联操作 
     save-update 表示主动方对象在调用save(),update()和saveOrUpdate()方法时对被关联对象执行保存或更新操作 
     delete  表示主动方对象在调用delete()方法时被关联对象执行删除操作
     delete-orphan 用在1-N关联中,表示主动方对象调用delete()方法时删除不被任何一个关联对象所引用的关联对象,多用于父子关联对象中。 
     all  等价于save-update和delete的联合使用
     注意:在实际开发中,级联通常用在1-N和1-1 关联关系中。而对于N-1和N-N关联使用级联操作则没有意义。此外,cascade属性值save-update最为常用。
     
      
    接下来将演示如何使用级联,以及级联使用哪些SQL语句?
    假设Customer类、Order类如下:
    要求:当添加一个顾客对象时,同时保存该顾客的所有订单。在BusinessService中添加如下代码:
     1 public class BusinessService{
     2     public static void main(String[] args){
     3           Customer customer = new Customer("lisi","123","李四","青岛","123123");
     4         Order order = new Order("3",new Date(),1000.0);//并没有传入customer对象
     5         //建立关联关系,实现级联保存
     6         customer.getOrders().add(order);
     7 
     8         Session session = HibernateUtils.getSession();
     9 
    10         Transaction trans = session.beginTransaction();
    11         session.save(customer);
    12         trans.commit();
    13         HibernateUtils.closeSession();
    14     }
    15 }
     1 Customer.hbm.xml
     2 <hibernate-mapping package="com.haiersoft.ch05.pojos">
     3     <class name="Custoemr" table="CUSTOMER">
     4     ... ...省略其它代码
     5         <!-- 1-N关联关系 -->
     6         <set name="orders" cascade="save-update">
     7             <key column="CUSTOMER_ID"/>
     8             <one-to-many class="Order"/>
     9         </set>
    10     </class>
    11 </hibernate-mapping>
    上述代码中,配置了级联保存或更新操作,当保存顾客对象时,会把其对应的订单对象级联保存。
    当运行main方法时,Hibernate执行了以下几条SQL语句:
    insert into CUSTOMER (USERNAME , PASSWORD , REALNAME , ADDRESS , MOBILE )
    values(?,?,?,?,?)   ①
    insert into ORDERS (ORDERNO , ORDERDATE , TOTAL , CUSTOMER_ID )
    values(?,?,?,?)   ②
    update ORDER set CUSTOMER_ID =?  where ID=?   ③
     
    上述结果中,执行了两条insert语句和一条update语句。
    Hibernate首先在CUSTOMER 表中插入一条记录(①),然后再往ORDERS表中插入一条没有customer参数的记录,也就是说,插入的这句中的参数CUSTOMER_ID是没有值的(②),那么就需要用到第三条update语句了,它会根据前两条语句的记录,从中获取得到CUSTOMER_ID、ORDERS表的ID值,然后给ORDERS表中的记录中的CUSTOMER_ID外键进行赋值(③)。从而完成两张表之间的关联关系。
     
    小结:级联关系方便了我们对有关联关系的数据操作,有了Hibernate的级联,你只要把有级联关系的主动关联方包含了被关联方的对象,那么我们只要对主动方进行操作就可以了,至于被关联方的数据它自己会按着我们关联关系被处理。
    也就是说,由上面的例子中Customer对象是主动关联方,而Order是被关联方。当需要想数据库插入一条Customer记录,并且还要把它相应的Order记录一并插入数据库中时,那么我们只需要把order对象添加到customer对象的orders属性中,并直接对customer进行操作就可以了,其中order对象并不需要传入Customer参数,也不需要手动的去操作order对象保存到数据库中,Hibernate会帮我们解决掉它。
     
    2. 级联控制反转
    在1-N关联关系中,通常讲控制权交给“N” 方,这可以在<set>元素中通过配置inverse属性来实现,当inverse=“true”时表示关联关系由对方维护。修改后的Customer.hbm.xml代码如下:
    <!-- 配置控制反转 -->
    <set name="orders" inverse="true" cascade="save-update">
    <key column="CUSTOMER_ID" />
    <one-to-many class="Order" />
    </set>
    通过上面的配置,设置将关联的控制权交给Order对象,所以在保存Customer对象前Order对象必须关联到该对象,如下代码:
     
     1 public class BusinessService{
     2     public static void main(String[] args){
     3         //添加客户和订单信息
     4         Customer customer = new Customer("lisi","123","李四","青岛市","123123123");
     5         Order order = new Order("3",new Date(),1000.0);
     6         //建立关联关系,实现级联保存
     7         customer.getOrders().add(order);
     8         //order对象必须关联customer对象,inverse才起作用
     9         order.setCustomer(customer);
    10 
    11 
    12         Transaction trans = session.beginTransaction();
    13         session.save(customer);
    14         trans.commit();
    15         HibernateUtils.closeSession();
    16 
    17     }
    18 }

    上述代码中,利用语句“order.setCustomer(customer)”实现了order到customer对象的关联,当运行main()方法时,Hibernate执行了以下两条insert语句。

    insert into CUSTOMER (USERNAME , PASSWORD , REALNAME , ADDRESS , MOBILE )
    values(?,?,?,?,?)   ①
    insert into ORDERS (ORDERNO , ORDERDATE , TOTAL , CUSTOMER_ID )
    values(?,?,?,?)   ②
    小结:当将关联的控制权交给“N”方时,无需执行update语句就可以完成两个关联对象之间的级联操作。
  • 相关阅读:
    Network (poj1144)
    C. Hongcow Builds A Nation
    ZYB loves Xor I(hud5269)
    D. Chloe and pleasant prizes
    Game(hdu5218)
    约瑟夫环的递推方法
    Misaki's Kiss again(hdu5175)
    Exploration(hdu5222)
    B. Arpa's weak amphitheater and Mehrdad's valuable Hoses
    C. Arpa's loud Owf and Mehrdad's evil plan
  • 原文地址:https://www.cnblogs.com/JamKong/p/4447090.html
Copyright © 2020-2023  润新知