读书人

hibernate联系关系映射之逐步分析

发布时间: 2012-09-14 11:53:44 作者: rapoo

hibernate关联映射之逐步分析

?

一对一关联映射(单双向)


1 单向

主要是配置文件上的标签配置
比如对于person和idcard两个pojo类。
Person持有idcard的引用。在person.hbm.xml里,person的主键要来源于idcard类,也就是共享idcard的

主键。配置:<id name= "id">
<generator constrained ="true">


2 双向
双向基本上是从单向演化而来.person.hbm.xml不变,在idcard.java里添加person引用,
在idcard.hbm.xml里加入<one-to-one>标签.
<one-to-one name="person"/>

?

二 多对一关联映射(单双向)


1 单向

多对一及其简单.
比如两个类,user和group.user为多的一方,group为一的一方,只要多的一方在类中持有一的一方的引用,

并且配置文件即user.hbm.xml里加入
<many-to-one name="group" column="groupid"/>
只这一句话便能建立起单向多对一关联映射.
但是,存储的时候要注意,先存一的一方,再存多的一方.
如果想让hibernate自动帮我们存储一的一方,那么就要修改上面的那句话:
<many-to-one name="group" column="groupid" cascade="all"/>
Cascade的意思是级联操作.有"all,save-update,delete,none",默认为none.
即如果要修改多的一方,那hibernate要先把一的一方改了.
这样我们只操作多的一方的增删查改就行了.

?

2 双向

看下面的一对多就知道,多对一和一对多是相对立的.
一对多关联映射利用了多对一关联映射原理

多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一
一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多

也就是说一对多和多对一的映射策略是一样的,只是站的角度不同

总的来说,在多的一方维护是比较好的.

三 一对多关联映射(单双向)


谁要对,那就在谁类里拿到对方的引用,那就再谁配置文件里配.


1 单向
还是两个类,class和student.

比起不用映射而言,student.hbm.xml不变,class.hbm.xml里多了的是:
<set name="students">
??? <key column="classesid"/>
??? <one-to-many column="classesid(必须和class.hbm.xml里的<key

column="classesid"/>一致)"/>

这样配置就可以存储.
有三种存储方式.这是第一种.因为是一的一端维护,所以多发两条update.步骤是先挨个存student,再存

class.
第二种先存class,把classid字段存到student里,再挨个存student.也就是反转.class.hbm.xml里:
<set name="students" inverse="true">
第三种把classid字段存到student里,不存student.只存class. 也就是反转并级联操作.class.hbm.xml里

:<set name="students" inverse="true" cascade="all">

?

关于存储上,基本上就这三种.无论是一对多还是多对一.个人认为比较麻烦.具体应用的时候可以考虑改进

.
多对一的时候,因为站在多的立场,如果不级联,要先存一,把一的数据加到多里的引用,再存多.级联了,因

为不用考虑一的关系,所以只存多.
而一对多的时候,反转不级联,就站在多的立场.也要先存一再存多.反转只是立场转为多对一,所以同上.
反转并级联,也同上.不考虑一.
不反转也不级联,因为站在一的立场,就要先存多.把多加入到一的set集合,再存一.所以呢,立场和先存谁

是对立的.

请消化一下以上的总结.
下面来看多对多.

?

四 多对多关联映射(单双向)

?

1 单向.

多对多涉及到第三方表.hibernate会自动生成.一般权限上会用到,比如RBAC模型.
如以往一样,两个类,user和role.同样,user持有role的引用,是一个set集合.(如前面的一对多)
Role.hbm.xml没有变化, User.hbm.xml里多的是:
<set name="roles" table="t_user_role">
??? <key column="userid"/>
??? <many-to-many column="roleid"/>
?? </set>
分析一下,set标签不用多说,table属性是指让hibernate自动建立第三方表名字叫"t_user_role",key标签

是指在此表中生成一个关联到本类(user的)叫userid的字段,
<many-to-many>标签里class属性引入类Role,并在t_user_role里生成一个关联到role的roleid字段.

在t_user_role表里,userid和roleid一并叫做复合主键.因为两者的联合有不可重复性.

其存储流程:1,存入role,2,用一个set集合接住role放到user的set里,(这里交叉存入比较容易看晕)3,挨

个存user.与上面的第二种存储方案差不多.
Load时候就简单,加载进来,在user里用一个遍历挨个从set里拿出来.就得到role表里的值.
执行存入的时候,hibernate就把表t_user_role各个值赋予了.


2 双向


基本上与单向一致.
Role里要持有user的引用,也是set集合,
Role.hbm.xml和user.hbm.xml配置差不多.
<set name="users" table="t_user_role" order-by="userid">
??? <key column="roleid"/>
??? <many-to-many column="userid"/>
?? </set>
注意两类对比,保持column属性值一致.

table属性值必须和单向关联中的table属性值一致
<key>中column属性值要与单向关联中的<many-to-many>标签中的column属性值一致
在<many-to-many>中的column属性值要与单向关联中<key>标签的column属性值一致

order-by="userid"属性是用来排序,按照t_user_role表的字段来排.

基本上,hibernate映射关系就是这些了.

?

读书人网 >软件架构设计

热点推荐