N的一段 | 1的一端 |
<manay-to-one name="group" column="groupid" cascade="save-update"> 维护了多指向1的关系 | Group |
1的一端(副表) | 1的另一端(主表) |
Person{id,name,idCard} 主键关联(双向): <one-to-one name="idCard" constrained="true"> <one-to-one>标签含义,指示hibernate怎么加载它的关联对象(idCard),默认是通过主键加载 constrained="true"表明当前主键存在一个约束,person的主键作为外键参照了idCard t_peron表内不会出现idCard列,因为可以通过外键参照t_idcard获得 默认启用了cascade,因为副表主键生成依赖于主表
Person{id,name,idCard} 唯一外键关联(单向) <id name="id"> <generator class="native"/> <many-to-one name="idCard" unique="true"/>
Person{id,name,idCard} 唯一外键关联(双向) 在1的一端存有多得一端的引用 数据库表和唯一外键映射单向一样,只是在1的一端添加<many-to-one>指导hibernate以此字段查询副表 |
IdCard{id, cardId,person}
<one-to-one name="person"/>
t_idcard表内也不会出现person列
IdCard{id, cardId} 跟N-1相同
IdCard{id, cardId,person} <one-to-one name="person" property-ref="idCard"> <one-to-one>默认通过主键查找,所以要用property-ref指示hibernate根据person的外键idCard来查找 |
N的一端 | 1的一端 |
例子:一班级有多个学生
单向 Class-------->Student Class{id,name,students(Set类型)}
在多的一端加入一个外键指向1的一端,维护的关系是多指向一。和一对多的策略一样,只是站在的角度不同
<id name="id">
<generator class="native">
<set name="students">
<key column="classesid"/>
<one-to-many class="com.xxx.Student"/>
这在1的一端维护关系的缺点:
1.<key name="classid">不能配置not-null="true",因为在添加class记录时首先添加student,暂且将t_student中的classid置为null,然后再添加class记录,待class记录添加完成生成classid后,再将此classid更新到前面添加的student记录。如果设置的话将导致无法保存
2.多的一端不维护关系,Student对象不知道自己属于哪个班级,所以要发出多余的update语句来更新关系
双向
Class{id,name,students(Set类型)}
1的一端
...和单向相同
<set name="students" inverse="true">
通常用多的一端来维护,让1的一端维护失效,使用inverse属性,结果为若保存classes,在添加完classid为null的student和classes记录本身之后,就不update学生的classesid字段了
这种情况下也有方法使1的一端也能维护,就是结合cascade属性
<set name="students" inverse="true" cascade="true">
这样的话在保存classes时会变成先保存classes记录,然后再保存student记录,不再有多余的update操作
inverse是控制关联关系的方向
cascade是产生操作上的连锁反应
|
Student{id,name}
<many-to-one name="class" class="Class" column="classid" not-null="true">
t_student表中生成列classid作为外键参照t_class中的主键id
Student{id,name,classes}
<many-to-one name="classes" column="classid">
会在t_student表中加入名为classesid的列,该列名必须和1的一端配置的key列名一致
|
N的一端 | N的一端 |
例子:用户和用户的角色
单向 User--------->Role
User{id,name,roles(Set类型)}
需要借助第三张表t_user_role来维护t_user表和t_role表的关系
<class name="xxx.User" table="t_user">
.....
<set name="roles" table="t_user_role">
<key clolumn="userid"/>
<many-to-many class="xxx.Role" column="roleid"></..>
t_user_role将使用userid和roleid联合主键,分别作为外键参考t_user和t_role表中的对应列
双向 User<--------->Role
User{id,name,roles(Set)}
...和单向的相同
<key>中的
|
Role{id,name}
<class name="xxx.Role" table="t_role"> <id name="id"> <generator class="native"/> <property name="name"/>
Role(id,name,users(Set)) ...
<set name="users" table="t_user_role" order-by="userid">
<key column="roleid"/>
<many-to-many class="xxx.User" column="userid"/>
table属性必须和单向关联中的table属性值一致
<key>中的column和<many-to-many>中的column要和单向关联中的对应属性值一致
|