Hibernate中cascade和inverse属性

引言

inverse和cascade都是维护关系的属性。inverse是可以理解为控制反转的意思,而casc理解为级联操作。

inverse

inverse是在一方维护多方的映射文件中才会有,也就是set集合设置的时候,在多方的映射文件中不会出现。当一方的控制权为false的时候,说明控制权还在自己手中,也就是一方可以维护着关系,但当为true的时候,一方将把控制权交给了多方了,导致一方在保存数据维护多方数据时,不会维护这层关系了。通过案例更好的理解。

案例:部门和员工的关系维护。

public class App3_inverse {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
            .configure()
            .addClass(Dept.class)   
            .addClass(Employee.class)   // 测试时候使用
            .buildSessionFactory();
    }

    // 1. 保存数据 
    @Test
    public void save() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("应用开发部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        dept.getEmps().add(emp_zs);
        dept.getEmps().add(emp_ls);  // inverse=true,  不会设置关联。
                                    //                 此时的关联应该通过员工方维护。


        // 保存
        session.save(emp_zs);
        session.save(emp_ls);
        session.save(dept); // 保存部门,部门下所有的员工  

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

    //2. 是否设置inverse,对获取数据的影响?   无.
    @Test
    public void get() {
        Session session = sf.openSession();
        session.beginTransaction();

        Dept dept = (Dept) session.get(Dept.class, 1);
        System.out.println(dept.getDeptName());
        System.out.println(dept.getEmps());

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

    // 3. 是否设置inverse,对解除关联关系影响?
    // inverse=false,  可以解除关联
    // inverse=true,  当前方(部门)没有控制权,不能解除关联关系(不会生成update语句,也不会报错)
    // 
    @Test
    public void removeRelation() {
        Session session = sf.openSession();
        session.beginTransaction();

        // 获取部门
        Dept dept = (Dept) session.get(Dept.class, 2);
        // 解除关系
        dept.getEmps().clear();

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


    //3. 是否设置inverse属性,在删除数据中对关联关系的影响?
    // inverse=false, 有控制权, 可以删除。先清空外键引用,再删除数据。
    // inverse=true,  没有控制权: 如果删除的记录有被外键引用,会报错,违反主外键引用约束!
    //                           如果删除的记录没有被引用,可以直接删除。
    @Test
    public void deleteData() {
        Session session = sf.openSession();
        session.beginTransaction();

        // 查询部门
        Dept dept = (Dept) session.get(Dept.class, 8);
        session.delete(dept);


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

也就是说,当我们通过一方来set多方额数据,一方维护多方的关系的时候,必须将inverse设置为false,也就是默认值,这样在session操作的时候,才能成功保存对应关系,如果设置为true,控制权交给多方,通过一方保存数据时,外键字段dept_id并没有插入到Employee这张表中,这样关系就会丢失。通过一方保存数据的意思就是通过dept对象来set员工的数据,最后保存的。

总结:

Inverse属性,是在维护关联关系的时候起作用的。
表示控制权是否转移。(在一的一方起作用)

Inverse , 控制反转。
Inverse = false 不反转; 当前方有控制权
True 控制反转; 当前方没有控制权

维护关联关系中,是否设置inverse属性对关联关系是否有影响:
1. 保存数据
有影响。
如果设置控制反转,即inverse=true, 然后通过部门方维护关联关系。在保存部门的时候,同时保存员工, 数据会保存,但关联关系不会维护。即外键字段为NULL
这里写图片描述
2. 获取数据
没有影响。
3. 解除关联关系?
有影响。
inverse=false, 可以解除关联
inverse=true, 当前方(部门)没有控制权,不能解除关联关系
(不会生成update语句,也不会报错)
4. 删除数据对关联关系的影响?
有影响。
inverse=false, 有控制权, 可以删除。先清空外键引用,再删除数据。
inverse=true, 没有控制权: 如果删除的记录有被外键引用,会报错,违反主外键引用约束! 如果删除的记录没有被引用,可以直接删除。

cascade

cascade 表示级联操作 【可以设置到一的一方或多的一方】
属性设置含义:
none 不级联操作, 默认值
save-update 级联保存或更新
delete 级联删除
save-update,delete 级联保存、更新、删除
all 同上。级联保存、更新、删除
一般是不会用到cascade属性的,因为如果设置一方级联对方,如果不小心删除部门的时候,部门下的所有员工都会被删除,这会造成很大的损失。这里就不在具体说明了。

public class App4_cascade {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
            .configure()
            .addClass(Dept.class)   
            .addClass(Employee.class)   // 测试时候使用
            .buildSessionFactory();
    }

    // 级联保存
    @Test
    public void save() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("财务部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        dept.getEmps().add(emp_zs);
        dept.getEmps().add(emp_ls);  

        // 保存
//      session.save(emp_zs);
//      session.save(emp_ls);
        session.save(dept); // 需要设置级联保存; 保存部门,部门下所有的员工  

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

    // 级联删除
    @Test
    public void delete() {
        Session session = sf.openSession();
        session.beginTransaction();

        Dept dept = (Dept) session.get(Dept.class,7);
        session.delete(dept); // 级联删除

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


    @Test
    public void bak() {
        Session session = sf.openSession();
        session.beginTransaction();

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


}

inverse与cascade区别?
作用的范围不同:
Inverse是设置在集合元素中的。
Cascade对于所有涉及到关联的元素都有效。
<many-to-one/><ont-to-many/>没有inverse属性,但有cascade属性

执行的策略不同
Inverse 会首先判断集合的变化情况,然后针对变化执行相应的处理。
Cascade 是直接对集合中每个元素执行相应的处理

执行的时机不同
Inverse是在执行SQL语句之前判断是否要执行该SQL语句
Cascade则在主控方发生操作时用来判断是否要进行级联操作

执行的目标不同
Inverse对于<ont-to-many><many-to-many>处理方式不相同。
对于<ont-to-many>,inverse所处理的是对被关联表进行修改操作。
对于<many-to-many>,inverse所处理的则是中间关联表
Cascade不会区分这两种关系的差别,所做的操作都是针对被关联的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值