Hibernate中一对多的相关操作

Hibernate中一对多的相关操作

什么叫做级联操作?
级联操作指的是,操作一个对象的时候,会同时操作其关联的对象。

级联是有方向性:
操作一的一方的时候,是否操作到多的一方。
操作多的一方的时候,是否操作到一的一方。


1、级联保存更新

测试代码1:

package com.pipi.hibernate03;

import myutils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

/*
    只对Dept.hbm.xml进行级联保存更新配置

    在Dept.hbm.xml中配置,为set标签加个cascade属性,值为save-update
        <set name="emps" cascade="save-update">

    此时Emp.hbm.xml中并没有设置cascade属性。
 */
public class Test02 {
    public static void main(String[] args) {

        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();

        // 创建1个部门
        Dept dept = new Dept(50, "皮皮部门", "北京");

        // 创建2个员工
        Emp emp1 = new Emp();
        emp1.setEname("张三");
        Emp emp2 = new Emp();
        emp2.setEname("李四");

        // 将部门与员工关联,此时只配置了Dept.hbm.xml级联保存更新
        emp1.setDept(dept);
        emp2.setDept(dept);
        dept.getEmps().add(emp1);
        dept.getEmps().add(emp2);

        // 只保存部门dept
        session.save(dept);

        transaction.commit();
    }
}


测试代码2:

package com.pipi.hibernate03;

import myutils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

/*
    只对Emp.hbm.xml进行级联保存更新配置

    在many-to-one标签中进行设置
        <many-to-one name="dept" cascade="save-update" class="com.pipi.hibernate03.Dept" column="deptno"/>

    此时Dept.hbm.xml中并没有配置cascade属性
 */
public class Test03 {
    public static void main(String[] args) {

        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();

        // 创建1个部门
        Dept dept = new Dept(50, "皮皮部门", "北京");

        // 创建2个员工
        Emp emp1 = new Emp();
        emp1.setEname("张三");
        Emp emp2 = new Emp();
        emp2.setEname("李四");

        // 设置关联,此时只对Emp.hbm.xml进行了级联保存配置
        emp1.setDept(dept);
        emp2.setDept(dept);
        dept.getEmps().add(emp1);
        dept.getEmps().add(emp2);

        // 只保存员工
        session.save(emp1);
        session.save(emp2);

        transaction.commit();
    }
}

测试代码3:

package com.pipi.hibernate03;

import myutils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

// Dept.hbm.xml,Emp.hbm.xml映射文件都配置了:级联保存更新
// 对象导航测试
public class Test04 {
    public static void main(String[] args) {

        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();

        // 创建1个部门
        Dept dept = new Dept(50, "皮皮部门", "北京");

        // 创建2个员工
        Emp emp1 = new Emp();
        emp1.setEname("张三");
        Emp emp2 = new Emp();
        emp2.setEname("李四");

        // 注意:这里只设置为,单向关联
        emp1.setDept(dept);
        dept.getEmps().add(emp2);

        // 只执行下面任意一条语句
        //session.save(emp1);  // 会发送几条insert语句?  答:3条
        //session.save(dept);  // 会发送几条insert语句?  答:2条
        session.save(emp2);  // 会发送几条insert语句?  答:1条

        transaction.commit();
    }
}

2、级联删除

测试代码:

package com.pipi.hibernate03;

import myutils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

/*
    在部门映射文件Dept.hbm.xml中的set标签中配置cascade属性,值为delete

        如果原来的级联属性有值,可以继续添加,用逗号隔开即可
        <set name="emps" cascade="save-update, delete">
 */
// 级联删除:删除一个部门,级联删除该部门的所有员工
public class Test05 {
    public static void main(String[] args) {

        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();

        // 默认的情况,没有配置级联删除
        Dept dept = session.get(Dept.class, 50);
        //session.delete(dept);  // 会先将该部门的所有员工的部门外键值设置为null,再删除该部门

        // 配置了级联删除
        session.delete(dept);  // 删除部门,同时级联删除该部门的所有员工

        transaction.commit();
    }
}

/*
    Hibernate中也可以删除一个员工,同时把部门级联删除。

    只不过这种需求是不合理的。很少用到。
 */

3、一对多设置了双向关联产生多余的SQL语句

在这里插入图片描述

测试代码:

package com.pipi.hibernate03;

import myutils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

/*
    一对多关系,设置双向关联,将会产生多余的sql语句执行。如何解决?

    让一的一方放弃外键管理。在Dept.hbm.xml映射文件中的set标签中配置inverse属性
        <set name="emps" cascade="save-update, delete" inverse="true">
 */
// 将7955员工的部门编号改为40部门
public class Test06 {
    public static void main(String[] args) {

        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();

        // 获取7955号员工
        Emp emp = session.get(Emp.class, 7955);

        // 获取40部门
        Dept dept = session.get(Dept.class, 40);

        // 设置双向关联
        emp.setDept(dept);
        dept.getEmps().add(emp);

        // 手动更新,当然持久态的对象改变会自动更新数据库
        session.update(emp);

        transaction.commit();
    }
}

解决多余的SQL语句

  • 单向维护:
  • 使一方放弃外键维护权:
    一的一方放弃。在set上配置inverse=”true”
  • 一对多的关联查询的修改的时候。(CRM练习)

4、区分cascade 和 inverse

测试代码:

package com.pipi.hibernate03;

import myutils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

// 区分cascade, inverse的区别
public class Test07 {
    public static void main(String[] args) {

        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();

        // 创建1个部门
        Dept dept = new Dept(50, "皮皮部门", "北京");

        // 创建1个员工
        Emp emp = new Emp();
        emp.setEname("张三");

        // 设置关联
        dept.getEmps().add(emp);

        // 前提:Dept.hbm.xml中配置了:cascade为save-update,inverse为true。
        session.save(dept);
        // 请问数据库中保存的信息是怎样的?
        // 部门50会插入到数据库中,张三员工也会插入到数据库中,张三的外键部门为null。

        transaction.commit();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值