一、一对一关联映射
1) 单项一对一关联映射
一对一关联映射原理:让两个实体的主键一样,这样就不需要加入多余的字段了
需要关联的一端(本端的主键根据对端生成):
<class name="com.bjpowernode.hibernate.Person" table="t_person">
<id name="id">
<!-- 采用foreign生成策略,forgeign会取得关联对象的标识 -->
<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>
被关联的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
</class>
</hibernate-mapping>
2)双向一对一关联映射
和单向比就是在被关联的一端加入<one-to-one>标签,需要在IdCard加入<one-to-one>标签,指示hibernate将关联对象Person根据主键加载上来。
<one-to-one>不影响存储,只影响加载。
需要关联的一端(本端的主键根据对端生成):
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Person" table="t_person">
<id name="id">
<!-- 采用foreign生成策略,forgeign会取得关联对象的标识 -->
<generator class="foreign">
<!-- property只关联对象 -->
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<one-to-one name="idCard" constrained="true"/>
</class>
</hibernate-mapping>
被关联的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
<one-to-one name="person"/>
</class>
</hibernate-mapping>
3)单向一对一唯一外键关联映射
一对一唯一外键关联映射其实是多对一的特例,采用<many-to-one>标签来映射,指定多的一端unique为true,这样就限制了多的一端的多重性为一,就是这样来映射的。
需要关联的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Person" table="t_person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="idCard" unique="true"/>
</class>
</hibernate-mapping>
被关联的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
</class>
</hibernate-mapping>
4)双向一对一唯一外键关联映射
一对一唯一外键关联双向采用<one-to-one>标签映射,必须指定<one-to-one>标签中的property-ref属性为关系字段的名称。
需要关联的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Person" table="t_person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="idCard" unique="true"/>
</class>
</hibernate-mapping>
被关联的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
<one-to-one name="person" property-ref="idCard"/>
</class>
</hibernate-mapping>
二、多对一关联映射
多对一关联映射原理:在多的一端加入一个外键,指向一的一端,在多的一端采用如下标签映射:<many-to-one name="group"column="groupid"/>
多的一端:
<hibernate-mapping>
<classtable="t_user" name="com.bjpowernode.hibernate.User">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-onename="group" cascade="save-update"column="groupid"/>
</class>
</hibernate-mapping>
一的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Group" table="t_group">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
三、一对多关联映射
1)单向一对多关联映射
一对多关联映射和多对一关联映射映射原理是一致的,都是在多的一端加入一个外键指向一的一端
它们的区别在于维护的关系不同:
a.多对一维护的关系是:多指向一的关系,有了此关系,在加载多的时候可以将一加载上来
b.一对多维护的关系是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来
在一一端维护关系存在缺陷:
1.因为多的一端Student不知道Classes的存在(也就是Student没有维护与Classes的关系)所以在保存Student的时候关系字段classesid是为null的,如果将该关系字段设置为非空,则将无法保存数据
2.另外因为Student不维护关系,而Classes维护关系,Classes就会发出多余的update语句,保证Classes和Student有关系,这样加载Classes的时候才可以把该Classes对应的学生加载上来
一的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students">
<!-- <key column="classesid" not-null="true"/>-->
<key column="classesid"/>
<one-to-many class="com.bjpowernode.hibernate.Student"/>
</set>
</class>
</hibernate-mapping>
多的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Student" table="t_student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
2)双向一对多关联映射
一对多双向关联的映射方式注意:
a.在一的一端的集合上采用<key>标签,在多的一端加入一个外键
b.在多的一端采用<many-to-one>标签
c.<key>标签和<many-to-one>标签加入的字段保持一致,否则会产生数据混乱
inverse属性:inverse属性可以用在一对多和多对多双向关联上,inverse属性默认为false,为false表示本端可以维护关系,如果inverse为true,则本端不能维护关系,会交给另一端维护关系,本端失效。所以一对多关联映射我们通常在多的一端维护关系,让一的一端失效,所以设置为inverse为true
inverse和cascade:inverse是控制方向上的反转,只影响存储;cascade是操作上的连锁反映
一的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students" inverse="true">
<!--
<key column="classesid" not-null="true"/>
-->
<key column="classesid"/>
<one-to-many class="com.bjpowernode.hibernate.Student"/>
</set>
</class>
</hibernate-mapping>
多的一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Student" table="t_student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="classes" column="classesid"/>
</class>
</hibernate-mapping>
四、多对多关系映射
1)单向User--->Role
具体映射:
<set name="roles" table="t_user_role">
<key column="user_id"/>
<many-to-many class="com.bjpowernode.hibernate.Role" column="role_id"/>
</set>
User一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="roles" table="t_user_role">
<key column="user_id"/>
<many-to-many class="com.bjpowernode.hibernate.Role" column="role_id"/>
</set>
</class>
</hibernate-mapping>
Role一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Role" table="t_role">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
2)双向User<--->Role
User一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="roles" table="t_user_role">
<key column="user_id" not-null="true"/>
<many-to-many class="com.bjpowernode.hibernate.Role" column="role_id" />
</set>
</class>
</hibernate-mapping>
Role一端:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Role" table="t_role">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="users" table="t_user_role">
<key column="role_id" not-null="true"/>
<many-to-many class="com.bjpowernode.hibernate.User" column="user_id"/>
</set>
</class>
</hibernate-mapping>