前边我们讲过了单向多对一的关联关系,即在Java代码-hbm.xml配置文件-数据库表格中只是描述了一种类中多个对象可以对应一个其他类对象的关联关系。我们需要在一个类中含有另一个类的引用变量,然后在包含类的hbm.xml文件中描述这个属性变量对应的外键和另一张表格中的主键的关联关系,使用<many-to-one>来描述这种关系,然后执行程序就会在数据库中自动生成这种单向一对多的关联关系。
今天我们来讲一讲基于上面的单向多对一的关联关系来描述另外一种双向一对多的关联关系,即站在一端来看是一对多,站在多的一端来看是多对一,关系维护是双向的。
1.域模型
和单向多对一的关联关系不同的是,除了在多的一端的Java类中存在一的一端的Java类的引用变量之外,我们还需要在一的一端的Java类中添加一个多的一端的Java类型的集合属性的引用。
需要注意的是:这个集合类型的属性必须是接口类型的,因为通过Hibernate获取的集合类型的对象时Hibernate内置的对象,这个类型的对象实现了集合接口却未继承其他类型的集合实现类,所以我们在赋值的时候才可以赋的上。
2.关系数据模型
和单向多对一一样,我们将多的一端的外键指向一的一端的表格的主键。
3.hbm.xml文件
多的一端的hbm.xml文件不变,而在一的一端的hbm.xml文件中,我们需要添加一个新的节点来描述从一的一端到多的一端的一对多的关联关系。
<set name="一端包含的多端类型的集合变量名称" table="集合变量类型的对应的表格的名称">
<key column="对应的多端的外键的名称">
<one-to-many class="多端的Java类型的名称">
<set>
3.测试双向一对多的关联关系的CURD操作
① 保存:
对于这种双向的关联关系,我们需要在两个类中的hbm.xml文件中进行维护,比较消耗我们的资源,那么我们可不可以只让一个类的hbm.xml来维护这种双向的关联关系呢?当然是可以的,我们选择多的一方来维护这种双向的关联关系,所以只需要在一的一方的hbm.xml文件中的set节点中指定inverse="true"就可以将这种维护双向关联关系的责任反转给多的一方了。这样一来,在保存的时候,我们先插入一的一方的对象,再插入多的一方的对象,就只会执行两条insert语句,而不会出现update语句了。
② 查询
先查询一的一方,和单向多对一一样会出现延迟加载的情况,即只有当使用包含的多的一方的对象时才会发送SQL语句进行查询。
通过一的一方的对象获取的多的一方的集合对象,是Hibernate框架的内置的集合对象,该类型有延迟加载和存放代理对象的功能。
4.hbm.xml文件中set节点的属性
① inverse:反转维护关联关系的对象,我们一般在一的一方即不含主键的一方的hbm.xml文件的set中设置这个属性值为true,从而将这种双向的关联关系反转交给多的一方的hbm.xml文件来单独维护。
② cascade:级联属性的设置,我们一般不设置级联属性,而采取手动的方式解除关联关系再进行删除操作。cascade值取delete时,那么我们在删除一的一端时就会将关联的多的一端的数据也全部删去;cascade值取save-update时,那么我们在保存一端的对象时,也会将多的一端的对象一并保存进去。
③ order-by:指定我们在获取对象时,按照order-by当中的值来进行排序之后再获取,注意这里边的值应该是SQL语言中的列名或者SQL函数,而不应该是类中的属性名称。