一、概述
双向 1-n 与 双向 n-1 是完全相同的两种情形
双向 1-n 需要在 1 的一端可以访问 n 的一端, 反之依然.
域模型:从 Order 到 Customer 的多对一双向关联需要在Order 类中定义一个 Customer 属性,而在 Customer 类中需定义存放 Order 对象的集合属性。
![](https://img.haomeiwen.com/i2058461/e06c33740eb668ea.png)
关系数据模型:ORDERS 表中的 CUSTOMER_ID 参照 CUSTOMER 表的主键
当 Session 从数据库中加载 Java 集合时, 创建的是 Hibernate 内置集合类的实例, 因此在持久化类中定义集合属性时必须把属性声明为 Java 接口类型
Hibernate 的内置集合类具有集合代理功能, 支持延迟检索策略
事实上, Hibernate 的内置集合类封装了 JDK 中的集合类, 这使得 Hibernate 能够对缓存中的集合对象进行脏检查, 按照集合对象的状态来同步更新数据库。
在定义集合属性时, 通常把它初始化为集合实现类的一个实例. 这样可以提高程序的健壮性, 避免应用程序访问取值为 null 的集合的方法抛出 NullPointerException
![](https://img.haomeiwen.com/i2058461/129dc8126941b45b.png)
二、案例
(1)跟上一个差不多,只增加了一个 集合属性
![](https://img.haomeiwen.com/i2058461/bdddea369c2a198d.png)
(2)Customer.hbm.xml
![](https://img.haomeiwen.com/i2058461/da42d067d868b008.png)
(3)新增方法1
![](https://img.haomeiwen.com/i2058461/391b210c347bd312.png)
(4)新增方法2,因为 1 的一端和 n 的一端都需要维护,所以多出了update
![](https://img.haomeiwen.com/i2058461/1409425b1ee83b7d.png)
(5)可以在 1 的一端set节点指定inverse=true,来使 1 的一端放弃维护关系!
建议设定set的inverse=true,建议先插入 1 的一端,后插入多的一端,好处是不会对出update语句
![](https://img.haomeiwen.com/i2058461/0117e7864768aebe.png)
![](https://img.haomeiwen.com/i2058461/4989cacfb3a14a52.png)
(6)返回的多的一端的集合时Hibernate内置的集合对象,该类型具有延迟加载和存放代理对象的功能。
![](https://img.haomeiwen.com/i2058461/d7f7b3f2d7bcdda6.png)
(7)update,无规则的
![](https://img.haomeiwen.com/i2058461/164be1c448bb8720.png)
![](https://img.haomeiwen.com/i2058461/1d491c6be539b387.png)
三、 <set>元素的 inverse 属性
在hibernate中通过对 inverse 属性的来决定是由双向关联的哪一方来维护表和表之间的关系. inverse = false 的为主动方,inverse = true 的为被动方, 由主动方负责维护关联关系
在没有设置 inverse=true 的情况下,父子两边都维护父子关系
在 1-n 关系中,将 n 方设为主控方将有助于性能改善(如果要国家元首记住全国人民的名字,不是太可能,但要让全国人民知道国家元首,就容易的多)
在 1-N 关系中,若将 1 方设为主控方:
①、会额外多出 update 语句。
②、插入数据时无法同时插入外键列,因而无法为外键列添加非空
四、<set>元素的cascade 属性
在对象 – 关系映射文件中, 用于映射持久化类之间关联关系的元素,<set>,<many-to-one>和<one-to-one>都有一个 cascade 属性, 它用于指定如何操纵与当前对象关联的其他对象.
![](https://img.haomeiwen.com/i2058461/edff33ecc9409f92.png)
目前的数据库是这样的
![](https://img.haomeiwen.com/i2058461/abdf98d343a14e63.png)
![](https://img.haomeiwen.com/i2058461/2630ed53f57e86b5.png)
如果删除某个已经有订单的客户,会抛出异常
![](https://img.haomeiwen.com/i2058461/6e0b211ab377af5b.png)
设定级联操作
![](https://img.haomeiwen.com/i2058461/a8e6846e2baf7b33.png)
再执行删除操作,就可以把该客户以及关联的订单同时删了
![](https://img.haomeiwen.com/i2058461/d477c9add561293c.png)
删除所有和当前对象关联的对象
![](https://img.haomeiwen.com/i2058461/7bd1a461642694aa.png)
![](https://img.haomeiwen.com/i2058461/5f355b80df343659.png)
save-update级联保存所有关联的新建的临时对象,并且级联更新所有关联的游离对:
![](https://img.haomeiwen.com/i2058461/13479af6831b4631.png)
![](https://img.haomeiwen.com/i2058461/0efcce3bef2adcd1.png)
五、<set>元素的 order-by 属性
<set>元素有一个 order-by 属性, 如果设置了该属性, 当 Hibernate 通过 select 语句到数据库中检索集合对象时, 利用 order by 子句进行排序,order-by 属性中还可以加入 SQL 函数
![](https://img.haomeiwen.com/i2058461/59070844566e88e1.png)
![](https://img.haomeiwen.com/i2058461/72c2b4d15ed34c05.png)
开发时不建议设定级联操作属性,建议使用手工的方式来处理
网友评论