zoukankan      html  css  js  c++  java
  • Hibernate Inverse属性的说明

     

    HibernateInverse属性的说明

    inverse常用于一对多双向关联关系中。

    Student(学生)和Class(班级)为例,它们之间的关系为一对多的关系,即一个学生只能属于一个班级,一个班级可以包含多个学生。

    学生类定义代码:

    Class Student{

      private int id;

      private String name;

      private Class class;

      //省略getter()setter()方法

    }

    班级类定义代码:

    Class Class{

      private int id;

      private String name;

      private Set students = new HashSet();

      //省略getter()setter()方法

    }

    Student类的映射文件:

    <class name="Student" table="STUDENT">

       <id name="id" type="int" column="ID">

          <generator class="native" /> 

       </id>

       <property name="name" type="string" column="NAME" />

       <many-to-one name="class" column="CLASS_ID" class="Class" cascade="save-update" />

    </class>

    Class类的映射文件:

    <class name="Class" table="CLASS">

       <id name="id" type="int" column="ID">

         <generator class="native" /> 

       </id>

       <property name="name" type="string" column="NAME" />

       <set name="students" table="STUDENT" cascade="save-update" inverse="false">

         <key column="CLASS_ID" />

         <one-to-many class="Student" />

       </set>

    </class>

    希望你能对这两个映射文件所表达的数据库模式有正确的认识。即STUDENT表中存在一个名为CLASS_ID的字段,它和CLASS表中的ID字段是主外键关系。那个inverse属性就是用来规定是由谁(StudentClass)来维护这个主外键关系的。

    inverse的默认值为false

    在处理逻辑代码中,如下:

    Class c1 = new Class();

    c1.setName("一班");

    Student s1 = new Student();

    Student s2 = new Student();

    s1.setName("Jason");

    s2.setName("Tom");

    c1.getStudents().add(s1);

    c2.getStudents().add(s2);

    s1.setClass(c1);

    s2.setClass(c1);   //注释1

    session.save(c1);

    上面的代码会使Hibernate执行五条SQL语句,其中前三条是insert插入语句,后两条是update更新语句。插入就不用说了,那么为什么还要有更新语句呢?这是因为Class类映射文件的<set>元素中指定了inverse="false",这就告之HibernateSTUDENT表与CLASS表的主外键关系是由Class类来维护的。当执行save后,执行了三条insert语句,这三条语句中的后两条是插入到STUDENT表的,它们的CLASS_ID字段是通过s1.getClass().getID()取出的,假如我将上面注释1”处修改为s2.setClass(c2);c2是另一个Class对象,可能是持久化对象),这样,主外键关系不就乱了吗。为了保证主外键关系,Hibernate在这种情况下会再执行两条update语句来更改STUDENT表中两个新插入记录的CLASS_ID字段,当然,这时CLASS_ID字段的取值是从c1对象中直接取得,而不再是s1.getClass().getID()方式了。

    如果我们将Class类映射文件的<set>元素中的inverse属性修改为true,这就是告诉HibernateClass类不维护主外键关系了,这个任务就交给了Student类。于是,我们再执行上面的代码,Hibernate就会只执行三条insert语句,而不会执行任何update语句。因为Hibernate会通过Student类的s1.getClass().getID()s2.getClass().getID()来确定CLASS_ID字段的值。

    故,为了节省数据库资源,省却不必要的update语句,我们一般建议在一对多双向关联关系中,将一方的inverse属性设置为true,即将主外键的关系交由多方来维护。

    打个比方:在一个公司中,是老板认识所有的员工容易,还是所有员工认识老板容易?

     





  • 相关阅读:
    Swift入门篇-Hello World
    Swift入门篇-swift简介
    Minecraft 插件 world edit 的cs 命令
    搭建本地MAVEN NEXUS 服务
    MC java 远程调试 plugin 开发
    企业内部从零开始安装docker hadoop 提纲
    javascript 命令方式 测试例子
    ca des key crt scr
    JSF 抽象和实现例子 (函数和属性)
    form 上传 html 代码
  • 原文地址:https://www.cnblogs.com/cookray/p/2806190.html
Copyright © 2011-2022 走看看