双向的一对多与多对一的关联关系:
1、双向的一对多的关联关系:
在双向的一对多的关联关系中,配置与单向的一对多的关联关系、双向的一对一关联关系也没有什么大的差别。在双向的一对多的关联关系中多的那一端与单向的一对多关联关系设置配置一致;但是在少的那一端呢?
在持久化对象中需要引用多的那一端的对象,在Xxx.hbm.xml中添加<many-to-one></many-to-one>标签;还需在该标签中添加name属性与column属性。name属性的值为引用对象的属性名;column值为外键的字段名
实例:在上面的单向一对多的关联关系中进行修改:
少的一端:不变
多的一端:
Java持久化对象实体:
public class Order {
private int id;
private String orderNum;
private Date orderTime;
private Account account;//引用少的那一端对象
//省去get/set方法
}
Xxx.hbm.xml配置:
<hibernate-mapping>
<class name="com.usc.geowind.lilin.bean.oneToMany.Order" table="Order">
<!-- type指明当前字段的类型 name对应实体中的属性名 -->
<id type="integer" name="id">
<!-- 提供ID自增的策略 native会根据数据库自行判断 -->
<generator class="native"/>
</id>
<property name="orderNum" type="string"></property>
<property name="orderTime" type="timestamp"></property>
<!-- 在双向的一对多的关系中,在多的一端添加该标签
name值为Java文件中少的一端对象的属性名,column为外键名,与另外的一端的xml文件配置中的外键一致 -->
<many-to-one name="account" column="acc_id"></many-to-one>
</class>
</hibernate-mapping>
值得注意的是:在添加数据的时候,添加多的一还是添加一的一端在效率上是有区别的:先添加多的一端,会先添加非外键的字段的值,在添加完一的一端时候,再回去通过Update语句去修改外键的值。而先添加一的那一端,再去添加多的一端时候,外键也会一起添加,从而不需要再去再次通过update语句修改多的那一端对应的数据库表中的外键的值。在需要考虑执行效率的时候,需要慎重选择数据添加方式。
亦可以在一端的Xxx.hbm.xml中的集合标签中添加inverse属性来选择是否实现控制权翻转。当inverse的值设置为true时候,控制权会调换多的一端,这样不会影响查询等操作。但是呢,在数据记录初始化,先插入多的一端,会导致多的一端你的数据库表中的相对应的外键为null,即是一对多的关联关系权维护不在一的那一端,二十在多的那端。这是我们则需要先添加一的那一端的数据记录。
实例:
<!-- inverse属性是是否调换关系维护的控制翻转权,即关系维护权是否交给另外一端 -->
<set name="" inverse="false">
<key column=""></key>
<one-to-many class=""/>
</set>
级联:
在数据的一端发生变化,另外一端跟着变化。在集合标签中设置属性Cascade。例如:
<set name="" inverse="false" cascade="all">
<key column=""></key>
<one-to-many class=""/>
</set>
在inverse="true" cascade="all"两属性一起使用时,级联关系须有,但是能起级联操作的只有在delete中
Cascade属性的取值有:
1、none:忽略其他关联的对象,默认值,无需设定。2、save-update:当session通过save(),update(),saveOrUpdate()方法来保存或更新对象时,级联保存所有关联的新建的临时对象,并且级联更新所有关联的游离对象。
3、persist:当session通过persist()方法来保存当前对象时,会级联保存所有关联的新建的临时对象。
4、merge:通过Session的merge()方法来保存当前对象时,会级联融合所有关联的游离对象。
5、delete:通过delete()删除当前对象时,会级联删除所有关联的对象。
6、lock:通过lock()把当前游离对象加入session缓存时,会把所有的游离对象也加入Session缓存中。
7、replicate:通过replicate()复制当前对象时,会级联复制所有关联的对象。
8、evict:通过evict()清除session缓存中对象时,会级联清除所有关联的对象。
9、refresh:通过refresh()刷新当前对象时,会级联刷新所有关联的对象。(刷新是指同步更新session缓存中数据)
10、all:save-update(),persist(),merge(),delete(),lock(),replicate(),evict()及refresh()的行为。
11、delete-orphan,删除所有和当前对象时,解除关联行为的对象。
12、all-delete-orphan; 通过delete()删除当前对象时,会级联删除所有关联的对象。