• Hibernate第五篇【inverse、cascade属性详解】


    前言

    上一篇博文已经讲解了一对多和多对一之间的关系了,一对多和多对一存在着关联关系(外键与主键的关系)。本博文主要讲解Inverse属性、cascade属性。这两个属性对关联关系都有影响

    Inverse属性

    Inverse属性:表示控制权是否转移..

    • true:控制权已转移【当前一方没有控制权】
    • false:控制权没有转移【当前一方有控制权】

    Inverse属性,是在维护关联关系的时候起作用的。只能在“一”的一方中使用该属性!Inverse属性的默认值为fasle,也就是当前一方是有控制权的

    这里写图片描述

    从一下的几个方面看看Inverse在维护关联关系时是否起作用

    • 保存数据
    • 获取数据
    • 解除关联关系
    • 删除数据对关联关系的影响

    保存数据

    将inverse属性设置为ture,使dept没有控制权

    
            <!--维护关系的是Set集合,对应employee表-->
            <set  cascade="save-update" name="set" table="employee" inverse="true">

    执行保存数据操作时,发现Hibernate只执行了三条SQL语句。employee表的外键并没有数据

    这里写图片描述

    结论:如果设置控制反转,即inverse=true, 然后通过部门方维护关联关系。在保存部门的时候,同时保存员工, 数据会保存,但关联关系不会维护。即外键字段为NULL


    查询数据

    设置inverse属性为true,那么部门一方是没有控制权的。

    
            <set  cascade="save-update" name="set" table="employee" inverse="true">
    

    我们在查看数据的时候,发现inverse属性对查询数据是没有影响的

    
            //查询出Dept对象
            Dept de = (Dept) session.get(Dept.class, 1);
            System.out.println(dept.getDeptName());
    
            System.out.println("-----------");
            //用到的时候再查询数据库,Hibernate的懒加载【后面会讲解】
            System.out.println(de.getSet());
    

    这里写图片描述


    解除关联关系

    部门和员工是存在外键的联系的,我们接下来看看inverse属性对于解除关联关系有没有影响

    • 当部门一方有权限时,即inverse属性为false
    
            //查找部门id为1的信息
            Dept dept1 = (Dept) session.get(Dept.class, 1);
    
            //清除关联信息
            dept1.getSet().clear();

    可以解除关联关系,employee的外键字段被设置为NULL了

    这里写图片描述

    • 当部门一方没有权限时,即inverse属性为true
    
            //查找部门id为2的信息
            Dept dept1 = (Dept) session.get(Dept.class, 2);
    
            //清除关联信息
            dept1.getSet().clear();

    不能解除关联关系

    这里写图片描述


    删除数据对关联关系的影响

    • 当部门一方有权限时,即inverse属性为false
            //查找部门id为2的信息
            Dept dept1 = (Dept) session.get(Dept.class, 2);
    
            //删除部门2
            session.delete(dept1);
    

    当有控制权的时候可以删除数据,先把外键设置为NULL,再删除数据!

    这里写图片描述

    • 当部门一方没有权限时,即inverse属性为true
            //查找部门id为1的信息
            Dept dept1 = (Dept) session.get(Dept.class, 1);
    
            //删除部门1
            session.delete(dept1);
    

    直接抛出异常,说该部门拥有外键,不能删除数据!

    这里写图片描述


    cascade属性

    cascade表示级联的意思,简单来说就是操作某一属性时,对其他关联字段的影响

    casecade属性不像inverse属性只能在“一”的一方设置,它可以在“一”的一方也可以在“多”的一方设置

    cascade有这么几个值

    • none 不级联操作, 默认值
    • save-update 级联保存或更新
    • delete 级联删除
    • save-update,delete 级联保存、更新、删除
    • all 同上。级联保存、更新、删除

    级联保存

    级联保存有什么用呢???我们来看个例子:

    • 如果在保存对象的时候,没有把相关的对象也一并保存进数据库,会出现错误
    • 因为它会发现dept是有外键的,而外键又是一个对象来保存着,这个对象在数据库表中并没有存在,因此会抛出异常
    
            //创建对象
            Dept dept = new Dept();
            dept.setDeptName("开发部");
    
            Employee zs = new Employee();
            zs.setEmpName("张珊");
            zs.setSalary(1111);
            Employee ls = new Employee();
            ls.setEmpName("李四");
            ls.setSalary(2222);
    
            //维护关系
            dept.getSet().add(zs);
            dept.getSet().add(ls);
    
            //保存dept对象
            session.save(dept);

    这里写图片描述

    如果我们在dept中设置了级联保存,那么Hibernate就会知道:保存dept的数据时,发现dept了外键,也把dept外键的对象保存在数据库之中

    
        <set name="set" table="employee" cascade="save-update" >

    这里写图片描述


    级联删除

    级联删除,这个对于我们来说风险太大了,如果删除了某些数据,会把另外有关联的数据也删除…在实际中我们一般不使用!

    • 在没有设置级联删除的时候,我们试试删除dept
            //删除部门为3的记录
            Dept dept1 = (Dept) session.get(dept.getClass(), 3);
            session.delete(dept1);
    

    它会先把3的外键对应的记录删除,再删除部门的数据

    这里写图片描述

    • 在设置级联删除的时候,我们试试删除dept
    
            <set name="set" table="employee" cascade="save-update,delete"  >
    • 级联删除数据
    
            //删除部门为4的记录
            Dept dept1 = (Dept) session.get(dept.getClass(), 4);
            session.delete(dept1);
    
    

    我们发现数据相关联的数据都没有了

    这里写图片描述


    cascade和inverse同时使用

    上面我们已经把cascade和inverse都介绍一遍了,那么cascade和inverse同时使用会怎么样呢???我们来测试一下

    • 设置dept没有控制权,但设置级联保存、删除
            <set name="set" table="employee" cascade="save-update,delete" inverse="true"  >
    • 添加一个dept对象
            //添加一个dept对象
            session.save(dept);

    如果我们单单设置了inverse属性为true,那么数据库中肯定是不能维护关联关系的【这里我们已经测试了】

    但是呢,现在也设置了级联保存,级联保存是可以让该对象相关的关联关系一并保存在数据库中的

    我们来看看结果:

    这里写图片描述

    从结果我们可以看出:inverse和cascade是相互独立的。cascade是不能影响着inverse的!

    总结

    上面的测试都是通过几个方面的,看起来有点多,因此我们总结一下

    inverse属性

    inverse属性只能在“一”的一方中设置。inverse=false表示有控制权,inverse=ture表示没有控制权

    • 在保存关联信息时
      • 有控制权—>可以保存相对应的关联数据
      • 没有控制权—>数据会保存,但是关联关系没有维护,也就是外键列为NULL
    • 在查询数据时
      • 有无控制权对查询数据没有任何影响
    • 在解除关联关系时
      • 有控制权—>可以解除关联关系
      • 没有控制权—>不能解除关联关系,不会生成update语句,也不会报错
    • 在删除数据时对关联关系的影响
      • 有控制权—>将外键的值设置为NULL,随后删除数据
      • 没有控制权—>如果删除的记录有被外键引用,会报错,违反主外键引用约束,如果删除的记录没有被引用,可以直接删除

    多对多关系的时候也是一样的,只不过多对多的关联关系是在中间表中

    cascade属性

    cascade有这么几个值:

    • none 不级联操作, 默认值
    • save-update 级联保存或更新
    • delete 级联删除
    • save-update,delete 级联保存、更新、删除
    • all 同上。级联保存、更新、删除

    我们可能使用到的往往是:save-update这个值,因为级联删除的风险太大了

    • 级联保存
      • 没有设置级联保存–>如果单单保存一个对象,而对象又存在外键时,那么就会抛出异常
      • 设置了级联保存–>那么就可以将对象以及有关联关系的对象一并保存
    • 级联删除
      • 没有设置级联删除–>在删除数据的时候,会把外键的字段设置为NULL,再删除当前一方的记录
      • 设置了级联删除–>把对象有关联关系的记录都删除了

    如果cascade和inverse同时设置时:

    • cascade和inverse是相互独立的,cascade不能影响着inverse

  • 相关阅读:
    2019-1-17水晶报表函数大全
    2019-1-17【水晶报表内功心法】--推拉之间
    2019-1-17水晶报表技巧总结【二】
    2019-1-16 水晶报表自动补空行
    2019-1-16水晶报表技巧总结【一】
    博客园添加访客人数
    2019-1-11存储过程的查看
    2019-1-11数据库重构
    lcx端口转发 linux版
    PentesterLab-From SQL Injection to Shell: PostgreSQL edition
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7202966.html
Copyright © 2020-2023  润新知