`

理解Hibernate中的Inverse属性

阅读更多
        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属性就是用来规定是由谁(Student或Class)来维护这个主外键关系的。
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",这就告之Hibernate:STUDENT表与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,这就是告诉Hibernate:Class类不维护主外键关系了,这个任务就交给了Student类。于是,我们再执行上面的代码,Hibernate就会只执行三条insert语句,而不会执行任何update语句。因为Hibernate会通过Student类的s1.getClass().getID()和s2.getClass().getID()来确定CLASS_ID字段的值。

        故,为了节省数据库资源,省却不必要的update语句,我们一般建议在一对多双向关联关系中,将一方的inverse属性设置为true,即将主外键的关系交由多方来维护。
        打个比方:在一个公司中,是老板认识所有的员工容易,还是所有员工认识老板容易?
分享到:
评论

相关推荐

    Hibernate中cascade与inverse属性详解

    cascade 和inverse是Hibernate中较为难理解的两个属性,此资料详细地介绍了这两个属性的用法。

    Hibernate中cascade与inverse属性详解.doc

    于Hibernate中 cascade 与 inverse 的理解。 您买的Hibernate书是哪一本呢? 孙卫琴的精通Hibernate,还是 深入浅出Hibernate还是那本。。。 我是两本都买了,总体来说还可以,但是,有的地方讲的比较书面化,比如...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    本章介绍一对多关联关系的映射方法,重点介绍inverse属性和cascade属性的用法。本章还将介绍通过Hibernate API来保存、修改和删除具有关联关系的对象的方法。 7.1 建立多对一的单向关联关系 148 7.1.1 [many-to-...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     7.2.1 元素的inverse属性  7.2.2 级联删除  7.2.3 父子关系  7.3 映射一对多双向自身关联关系  7.4 改进持久化类  7.5 小结  7.6 思考题 第8章 通过Hibernate操纵对象(上)  8.1 Java对象在JVM中的生命...

    精通Hibernate:对象持久化技术第二版part3

    本章介绍一对多关联关系的映射方法,重点介绍inverse属性和cascade属性的用法。本章还将介绍通过Hibernate API来保存、修改和删除具有关联关系的对象的方法。 7.1 建立多对一的单向关联关系 148 7.1.1 [many-to-...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     7.2.1 元素的inverse属性  7.2.2 级联删除  7.2.3 父子关系  7.3 映射一对多双向自身关联关系  7.4 改进持久化类  7.5 小结  7.6 思考题 第8章 通过Hibernate操纵对象(上)  8.1 Java对象在JVM中的生命...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     7.2.1 元素的inverse属性  7.2.2 级联删除  7.2.3 父子关系  7.3 映射一对多双向自身关联关系  7.4 改进持久化类  7.5 小结  7.6 思考题 第8章 通过Hibernate操纵对象(上)  8.1 Java对象在JVM中的生命...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     7.2.1 元素的inverse属性  7.2.2 级联删除  7.2.3 父子关系  7.3 映射一对多双向自身关联关系  7.4 改进持久化类  7.5 小结  7.6 思考题 第8章 通过Hibernate操纵对象(上)  8.1 Java对象在JVM中的生命...

    Java面试宝典2010版

    9、hibernate的inverse属性的作用? 13、在DAO中如何体现DAO设计模式? 14、spring+Hibernate中委托方案怎么配置? 15、spring+Hibernate中委托方案怎么配置? 16. hibernate进行多表查询每个表中各取几个字段,也...

    最新Java面试宝典pdf版

    9、hibernate的inverse属性的作用? 122 13、在DAO中如何体现DAO设计模式? 123 14、spring+Hibernate中委托方案怎么配置? 123 15、spring+Hibernate中委托方案怎么配置? 123 16. hibernate进行多表查询每个表中各取几...

    Java面试笔试资料大全

    9、hibernate的inverse属性的作用? 122 13、在DAO中如何体现DAO设计模式? 123 14、spring+Hibernate中委托方案怎么配置? 123 15、spring+Hibernate中委托方案怎么配置? 123 16. hibernate进行多表查询每个表中各取几...

    JAVA面试宝典2010

    9、hibernate的inverse属性的作用? 122 13、在DAO中如何体现DAO设计模式? 123 14、spring+Hibernate中委托方案怎么配置? 123 15、spring+Hibernate中委托方案怎么配置? 123 16. hibernate进行多表查询每个表中各取几...

    Java面试宝典-经典

    9、hibernate的inverse属性的作用? 122 13、在DAO中如何体现DAO设计模式? 123 14、spring+Hibernate中委托方案怎么配置? 123 15、spring+Hibernate中委托方案怎么配置? 123 16. hibernate进行多表查询每个表中各取几...

    java面试题大全(2012版)

    9、hibernate的inverse属性的作用? 122 13、在DAO中如何体现DAO设计模式? 123 14、spring+Hibernate中委托方案怎么配置? 123 15、spring+Hibernate中委托方案怎么配置? 123 16. hibernate进行多表查询每个表中各取几...

    Java面试宝典2012版

    9、hibernate的inverse属性的作用? 122 13、在DAO中如何体现DAO设计模式? 123 14、spring+Hibernate中委托方案怎么配置? 123 15、spring+Hibernate中委托方案怎么配置? 123 16. hibernate进行多表查询每个表中各...

    java面试宝典2012

    9、hibernate的inverse属性的作用? 134 13、在DAO中如何体现DAO设计模式? 134 14、spring+Hibernate中委托方案怎么配置? 134 15、spring+Hibernate中委托方案怎么配置? 134 16. hibernate进行多表查询每个表中各取几...

    Java面试宝典2012新版

    9、hibernate的inverse属性的作用? 122 13、在DAO中如何体现DAO设计模式? 123 14、spring+Hibernate中委托方案怎么配置? 123 15、spring+Hibernate中委托方案怎么配置? 123 16. hibernate进行多表查询每个表中各取几...

Global site tag (gtag.js) - Google Analytics