Hibernate关系映射
1.关联映射
概念:关联映射,就是将关联关系映射到数据库中,所谓的关联关系,在对象模型中,就是一个或多个引用
分类:
(1)多对一关联映射
many-to-one
多对一关联映射原理:在多的一端加入一个外键,指向一的一端
在多的一端采用如下标签映射:
<many-to-one name="group" column="groupId"/>
(2)一对一关联映射
one-to-one
A主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联
示例1:
hibernate一对一主键关联映射(单向关联Person--->IdCard)
一对一关联映射原理:让两个实体的主键一样,这样就不需要加入多余的字段了(扩展性不好)
<class name="com.ys.hibernate.Person" table="t_person"> <id name="id"> <!-- 采用foreign生成策略,会取得关联对象的标识 --> <generator class="foreign"> <!-- property指关联对象 --> <param name="property">idCard</param> </generator> </id> <property name="name" /> <!-- one-to-one指示hibernate如何加载其关联对象,默认根据主键加载 也就是拿到关系字段值,根据对端的主键来加载关联对象 constrained="true"表示,当前主键(Person的主键)还是一个外键 参照了对端的主键(IdCard的主键),也就是会生成外键约束语句 --> <one-to-one name="idCard" constrained="true" /> </class>
示例2:
hibernate一对一主键关联映射(双向关联Person<--->IdCard)
需要在IdCard加入<one-to-one>标签,
指示hibernate将关联对象Person根据主键加载上来
<one-to-one>不影响存储,只影响加载
<one-to-one>标签fetch属性默认为"join".
B唯一外键关联:外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系
示例1:
hibernate一对一唯一外键关联映射(单向关联Person--->IdCard)
一对一唯一外键关联映射,其实是多对一的特例
采用<many-to-one>标签来映射,指定多的一端unique为true,
这样就限制了多的一端的多重性为一,就是这样来映射的。
<many-to-one name="idCard" unique="true"/>
示例2:
hibernate一对一唯一外键关联映射(双向关联Person<--->IdCard)
一对一唯一外键关联双向,采用<one-to-one>标签映射,
必须指定<one-to-one>标签中的property-ref属性为关系字段的名称
<one-to-one name="person" property-ref="idCard"/>
(3)一对多关联映射
one-to-many
示例1:
hibernate一对多关联映射(单向Classes--->Student)
一对多和多对一的映射原理是一样的,都是在多的一端加入一个外键指向一的一端
它们的区别在于维护的关系不同:
*多对一维护的关系:多指向一的关系,如果维护了多指向一的关系,那么加载多的时候会把一加载上来
*一对多维护的关系:一指向多的关系,如果维护了一指向多的关系,那么加载一的时候会把多加载上来
在一的一端维护关系存在缺陷:
*因为多的一端Student不知道Classes的存在(也就是Student没有维护与Classes的关系)
所以在保存Student的时候关系字段classesId是为null的,如果将该字段设置为非空,则将无法保存数据
*另外因为Student不维护关系,而Classes维护关系,Classes就会发出多余的update语句,保证Classes和Student有关系,这样加载Classes的时候才能把该Classes对应的学生集合加载上
<set name="students"> <!-- <key column="classesId" not-null="true"/>--保存不成功 --> <key column="classesId" />--会发出多余的update语句来维持关系 <one-to-many class="com.ys.hibernate.Student" /> </set>
示例2:
hibernate一对多关联映射(双向Classes<--->Student)
采用一对多双向关联映射的目的主要是为了解决一对多单向关联的缺陷
而不是需求驱动的
一对多双向关联的映射方式:
*在一的一端的集合上采用<key>标签,在多的一端加入一个外键
*在多的一端采用<many-to-one>标签
<many-to-one name="classes" column="classesId" />
!!!注意:
<key>标签和<many-to-one>标签加入的字段保持一致,否则会产生数据混乱
(4)多对多关联映射
many-to-many
示例1:
hibernate多对多关联映射(单向User--->Role)
具体映射:
<set name="roles" table="t_user_role">
<key column="user_id" />
<many-to-many class="com.ys.hibernate.Role" column="role_id" />
</set>
把第三张表也抽取出一个类出来,使用两个many-to-one来完成
示例2:
hibernate多对多关联映射(双向User<--->Role)
具体映射:
<set name="roles" table="t_user_role"> <key column="user_id" /> <many-to-many class="com.ys.hibernate.Role" column="role_id" /> </set>
需要注意:
*生成的中间表名称必须一样
*生成的中间表中的字段必须一样