hibernate中的关系映射02级联设置和关系权反转

如果要了解多对多的映射,首先需要学习级联设置和关系权反转

一、级联保存
1、测试级联保存

测试:复制前面的例子,只保存Customer数据,不保存Order数据,会报告错误
/**
 * 保存操作 - 级联保存
 */
@Test
public void testCascadeSave(){

    //准备数据
    ...
    //建立一对多双向关系
   ...
    //保存数据
    session.save(customer);
    //session.save(o1);
    //session.save(o2);

    //数据提交
    ...
}


2、配置级联保存
级联操作: 就是操作一个对象的时候,想同时操作它的关联对象。
在Customer的一对多中配置级联保存,再次进行测试,保存成功
<set name="orders" cascade="save-update">

配置了级联保存后,这里可以只设置Customer对order的单项关联
//建立一对多单向关系
customer.getOrders().add(o1);
customer.getOrders().add(o2);
//o1.setCustomer(customer);
//o2.setCustomer(customer);

二、级联删除

1、测试级联删除
(1)如果没有级联删除,那么在删除客户的时候,会把订单表的customer_id外键值设置为null ,
(2)也可以事先把订单列表取出来,业务实现上先删除订单,然后再删除客户
    /**
     * 级联删除
     */
    @Test
    public void testCascadeDelete(){
        
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();

        Customer customer = session.get(Customer.class, 1L);
       /* Set<Order> orders = customer.getOrders();
        for (Order order : orders) {
            session.delete(order);
        }*/
        session.delete(customer);

        tx.commit();
        session.close();
    }
}

2、配置级联删除
有了级联删除,那么只删除客户,hibernate会同时把该客户的所有订单删除
<set name="orders" cascade="save-update,delete">

三、同时设置级联保存和删除

<set name="orders" cascade="all">


四、什么叫关系权反转

inverse 配置:表示是否把关联关系的维护权反转(放弃)
false:默认值,不反转(不放弃)
true:反转(放弃)

五、关系反转

1、测试关系反转
运行级联保存的测试用例, 查看日志中的sql语句
插入一个用户、两个订单,应该执行3个insert语句
但是发现日志中多打印了两个update语句

默认情况下inverse的值是false:
<set name="orders" cascade="all" inverse="false">
表示customer 一方需要维护关联关系,因此需要维护外键,有关联记录生成时,会做外键的更新操作。
而这个更新操作是没有必要的, 因为order插入的时候已经将外键值插入。
所以customer中的update的语句是多余的

2、优化
放弃customer方的外键维护
<set name="orders" cascade="all" inverse="true">

注意:使用关系反转时要将双向关系都建立起来
//建立双向关联关系
customer.getOrders().add(order1);
customer.getOrders().add(order2);

order1.setCustomer(customer);
order2.setCustomer(customer);

重新测试,发现只有三条insert语句
补充:通常在一对多的关联配置中,多方无法放弃关系维护权,所以应该放弃 1  方的维护权,意味着在 1 方加上 inverse=true 配置


2、第二种优化方式:不使用关系反转
(1)不设置前面的关系反转
(2)保存时,只保存订单,只在订单方维护关系
//建立一对多双/单向关系
//customer.getOrders().add(o1);
//customer.getOrders().add(o2);
o1.setCustomer(customer);
o2.setCustomer(customer);

//保存数据
//session.save(customer);
session.save(o1);
session.save(o2);
(3)在订单端设置级联保存
<!-- 多对一配置 -->
<many-to-one name="customer" class="Customer" column="customer_id" cascade="save-update"/>

但是,这种方式在业务逻辑上不通顺,应该先有客户后有订单
因此,最好的优化方式是在“一方”设置“级联保存”


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值