博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate - Inverse属性的说明
阅读量:6968 次
发布时间:2019-06-27

本文共 2220 字,大约阅读时间需要 7 分钟。

 

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,即将主外键的关系交由多方来维护。

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

 

转载于:https://www.cnblogs.com/cookray/archive/2012/12/06/2806190.html

你可能感兴趣的文章
// 打印用户自定义常量
查看>>
ubuntu下cairo-dock安装以及3D效果设置
查看>>
水晶头
查看>>
Linux 软件安装
查看>>
mysql查询单条数据查询
查看>>
网络数据采集-读取文档
查看>>
我的友情链接
查看>>
第一个交换机的实验(单臂路由)
查看>>
谷歌地图 3
查看>>
MCSA / Windows Server 2016 用MAP工具进行IT资产评估I和虚拟化部署准备
查看>>
P6Spy和sping配合显示真正的SQL
查看>>
我的友情链接
查看>>
mysql(mariadb)基于ssl主从复制
查看>>
(1)SpringCloud相关知识资源整理
查看>>
定时任务与手动执行脚本时的一个重要注意事项
查看>>
EditPlus常用快捷键
查看>>
26次课(正则介绍 grep)
查看>>
Spark的Shuffle过程
查看>>
ISIS----RIP
查看>>
windows 8 应用小技巧(31-35)
查看>>