总结:
在映射一对多的双向关联关系时,应该在“one”方把inverse设为true,这样可以提高性能
关于inverse在one-to-many外键关联(双向关联)中的作用:P.155 孙卫琴-《精通Hibernate:Java对象持久化技术详解》
Order.hbm.xml设置:
<class name="mypack.Order" table="ORDERS">
<id name="id" type="long" column="ID">
<generator class="increment" />
</id>
<property name="orderNumber" type="string">
<column name="ORDER_NUMBER" length="15" />
</property>
<many-to-one name="customer"
column="CUSTOMER_ID"
class="mypack.Customer"
cascade="save-update" />
</class>
Customer.hbm.xml设置:
<class name="mypack.Customer" table="CUSTOMERS">
<id name="id" type="long" column="ID">
<generator class="increment" />
</id>
<property name="name" type="string">
<column name="NAME" length="15" />
</property>
<set name="orders"
cascade="all"
inverse="true"> <!-- inserse="true" -->
<key column="CUSTOMER_ID" />
<one-to-many class="mypack.Order" />
</set>
</class>
以上代码表明在Customer和Order的双向关联关系中,Customer端的关联只是Order端关系的镜像。当Hibernate探测到持久化对象Customer和Order的状态均发生变化时,
公按照Order对象状态的变化来同步更新数据库。
----------------------------------------------------------------------------------------------
我理解的是这两者是没什么关系的,各管各的事情。
inverse只有在集合映射中才有,当inverse = true,字面意思好像是反转,由对方来维护关系,但实际还要看对方的配置,实际意思就是我不维护这个关系。
当inverse = false意思就是我要维护这个关系,维护关系表现在行动上就是对于加入到这个集合或者从集合中移除的对象,对它的外键进行更新操作,使它与自己关联起来,将它的外键值设为null就是与自己脱离关系,或者是对中间表的操作(增删中间表的关联记录)。
inverse不会去删除对方这个对象,而cascade则可以级联删除或插入对方。
inverse作用的基础是对方这个对象在数据库中存在,与cascade配合使用,作用的顺序也是cascade在前inverse在后。
所以对于多对一双向关联,因为多方已经可以建立关联关系,所以在"one"方一般会设inverse = true。
对于多对多双向关联来说,则至少要有一方设置进行关联维护。
----------------------------------------------------------------------------------------------
inverse主要用于 双向关联的set+one-to-many(或many-to-many)有效,
对many-to-one, one-to-one无效。cascade对关系标记都有效。
cascade和inverse有什么区别?
可以这样理解,cascade定义的是关系两端对象到对象的级联关系;而inverse定义的是关系和对象的级联关系。
inverse对集合对象整体起作用,cascade对集合对象中的一个一个元素起作用,如果集合为空,那么cascade不会引发关联操作。
比如将集合对象置为null, school.setStudentSet(null)
inverse导致hibernate执行:udpate STUDENT set SCHOOL_ID=null where SCHOOL_ID=?
cascade则不会执行对STUDENT表的关联更新, 因为集合中没有元素。
再比新增一个school, session.save(school)
inverse导致hibernate执行:
for( 对(school的每一个student ){
udpate STUDENT set SCHOOL_ID=? where STUDENT_ID=? //将学生的school_id改为新的school的id
}
cascade导致hibernate执行:
for( 对school的每一个student ){
session.save(aStudent); //对学生执行save操作
}
extends:如果改变集合中的部分元素(比如新增一个元素),
inverse: hibernate先判断哪些元素改变了,对改变的元素执行相应的sql
cascade: 它总是对集合中的每个元素执行关联操作。
(在关联操作中,hibernate会判断操作的对象是否改变)
两个起作用的时机不同:
cascade:在对主控方操作时,级联发生。
inverse: 在flush时(commit会自动执行flush),对session中的所有set,hibernate判断每个set是否有变化,
对有变化的set执行相应的sql,执行之前,会有个判断:if( inverse == true ) return;可以看出cascade在先,inverse在后。
inverse 对set + one-to-many 和 set + many-to-many 起的作用不同。hibernate生成的sql不同。
对one-to-many,hibernate对many方的数据库表执行update语句。
对many-to-many, hibernate对关系表执行insert/update/delte语句,注意不是对many方的数据库表而是关系表。
在映射一对多的双向关联关系时,应该在“one”方把inverse设为true,这样可以提高性能
关于inverse在one-to-many外键关联(双向关联)中的作用:P.155 孙卫琴-《精通Hibernate:Java对象持久化技术详解》
Order.hbm.xml设置:
<class name="mypack.Order" table="ORDERS">
<id name="id" type="long" column="ID">
<generator class="increment" />
</id>
<property name="orderNumber" type="string">
<column name="ORDER_NUMBER" length="15" />
</property>
<many-to-one name="customer"
column="CUSTOMER_ID"
class="mypack.Customer"
cascade="save-update" />
</class>
Customer.hbm.xml设置:
<class name="mypack.Customer" table="CUSTOMERS">
<id name="id" type="long" column="ID">
<generator class="increment" />
</id>
<property name="name" type="string">
<column name="NAME" length="15" />
</property>
<set name="orders"
cascade="all"
inverse="true"> <!-- inserse="true" -->
<key column="CUSTOMER_ID" />
<one-to-many class="mypack.Order" />
</set>
</class>
以上代码表明在Customer和Order的双向关联关系中,Customer端的关联只是Order端关系的镜像。当Hibernate探测到持久化对象Customer和Order的状态均发生变化时,
公按照Order对象状态的变化来同步更新数据库。
----------------------------------------------------------------------------------------------
我理解的是这两者是没什么关系的,各管各的事情。
inverse只有在集合映射中才有,当inverse = true,字面意思好像是反转,由对方来维护关系,但实际还要看对方的配置,实际意思就是我不维护这个关系。
当inverse = false意思就是我要维护这个关系,维护关系表现在行动上就是对于加入到这个集合或者从集合中移除的对象,对它的外键进行更新操作,使它与自己关联起来,将它的外键值设为null就是与自己脱离关系,或者是对中间表的操作(增删中间表的关联记录)。
inverse不会去删除对方这个对象,而cascade则可以级联删除或插入对方。
inverse作用的基础是对方这个对象在数据库中存在,与cascade配合使用,作用的顺序也是cascade在前inverse在后。
所以对于多对一双向关联,因为多方已经可以建立关联关系,所以在"one"方一般会设inverse = true。
对于多对多双向关联来说,则至少要有一方设置进行关联维护。
----------------------------------------------------------------------------------------------
inverse主要用于 双向关联的set+one-to-many(或many-to-many)有效,
对many-to-one, one-to-one无效。cascade对关系标记都有效。
cascade和inverse有什么区别?
可以这样理解,cascade定义的是关系两端对象到对象的级联关系;而inverse定义的是关系和对象的级联关系。
inverse对集合对象整体起作用,cascade对集合对象中的一个一个元素起作用,如果集合为空,那么cascade不会引发关联操作。
比如将集合对象置为null, school.setStudentSet(null)
inverse导致hibernate执行:udpate STUDENT set SCHOOL_ID=null where SCHOOL_ID=?
cascade则不会执行对STUDENT表的关联更新, 因为集合中没有元素。
再比新增一个school, session.save(school)
inverse导致hibernate执行:
for( 对(school的每一个student ){
udpate STUDENT set SCHOOL_ID=? where STUDENT_ID=? //将学生的school_id改为新的school的id
}
cascade导致hibernate执行:
for( 对school的每一个student ){
session.save(aStudent); //对学生执行save操作
}
extends:如果改变集合中的部分元素(比如新增一个元素),
inverse: hibernate先判断哪些元素改变了,对改变的元素执行相应的sql
cascade: 它总是对集合中的每个元素执行关联操作。
(在关联操作中,hibernate会判断操作的对象是否改变)
两个起作用的时机不同:
cascade:在对主控方操作时,级联发生。
inverse: 在flush时(commit会自动执行flush),对session中的所有set,hibernate判断每个set是否有变化,
对有变化的set执行相应的sql,执行之前,会有个判断:if( inverse == true ) return;可以看出cascade在先,inverse在后。
inverse 对set + one-to-many 和 set + many-to-many 起的作用不同。hibernate生成的sql不同。
对one-to-many,hibernate对many方的数据库表执行update语句。
对many-to-many, hibernate对关系表执行insert/update/delte语句,注意不是对many方的数据库表而是关系表。
cascase 对set都是一致的,不管one-to-many还是many-to-many。都简单地把操作传递到set中的每个元素。所以它总是更新many方的数据库表。
转自:私塾在线