一對一關(guān)聯(lián)映射(單雙向)
1 單向
主要是配置文件上的標(biāo)簽配置
比如對于person和idcard兩個pojo類。
Person持有idcard的引用。在person.hbm.xml里,person的主鍵要來源于idcard類,也就是共享idcard的
主鍵。配置:<id name= "id">
<generator class="foreign(而不是原來的native)">
<param name="property(必須是這個)">idcard(用來關(guān)聯(lián)到person類的idcard屬性)</param>
</generator>
</id>
另外主要配置<one-to-one>標(biāo)簽,此標(biāo)簽的作用是指示hibernate怎么加載它的關(guān)聯(lián)對象,默認(rèn)根據(jù)主鍵加
載.
標(biāo)簽name屬性是通過person類的idcard,關(guān)聯(lián)到idcard類.
Constrained屬性主要聲明是外鍵約束.
<one-to-one name="idcard" constrained ="true">
2 雙向
雙向基本上是從單向演化而來.person.hbm.xml不變,在idcard.java里添加person引用,
在idcard.hbm.xml里加入<one-to-one>標(biāo)簽.
<one-to-one name="person"/>
二 多對一關(guān)聯(lián)映射(單雙向)
1 單向
多對一及其簡單.
比如兩個類,user和group.user為多的一方,group為一的一方,只要多的一方在類中持有一的一方的引用,
并且配置文件即user.hbm.xml里加入
<many-to-one name="group" column="groupid"/>
只這一句話便能建立起單向多對一關(guān)聯(lián)映射.
但是,存儲的時候要注意,先存一的一方,再存多的一方.
如果想讓hibernate自動幫我們存儲一的一方,那么就要修改上面的那句話:
<many-to-one name="group" column="groupid" cascade="all"/>
Cascade的意思是級聯(lián)操作.有"all,save-update,delete,none",默認(rèn)為none.
即如果要修改多的一方,那hibernate要先把一的一方改了.
這樣我們只操作多的一方的增刪查改就行了.
2 雙向
看下面的一對多就知道,多對一和一對多是相對立的.
一對多關(guān)聯(lián)映射利用了多對一關(guān)聯(lián)映射原理
多對一關(guān)聯(lián)映射:在多的一端加入一個外鍵指向一的一端,它維護(hù)的關(guān)系是多指向一
一對多關(guān)聯(lián)映射:在多的一端加入一個外鍵指向一的一端,它維護(hù)的關(guān)系是一指向多
也就是說一對多和多對一的映射策略是一樣的,只是站的角度不同
總的來說,在多的一方維護(hù)是比較好的.
三 一對多關(guān)聯(lián)映射(單雙向)
誰要對,那就在誰類里拿到對方的引用,那就再誰配置文件里配.
1 單向
還是兩個類,class和student.
比起不用映射而言,student.hbm.xml不變,class.hbm.xml里多了的是:
<set name="students">
<key column="classesid"/>
<one-to-many class="Student"/>
</set>
分析一下,用set標(biāo)簽的出發(fā)點是因為class類里持有student的引用(一個set集合),至于為什么是集合而不
是如以往的一個student直觀的引用,是因為外鍵要設(shè)的不只是一個.如果不能理解,就直接理解為必須用
set標(biāo)簽就成了.
那么name屬性是拿到引用,子標(biāo)簽key的column屬性是在student里加一個字段,名字叫classesid,
而one-to-many標(biāo)簽是指向student類.
如果<hibernate-mapping package="com.bjsxt.hibernate">這樣寫,
那么在one-to-many標(biāo)簽直接跟類名.
需要注意的是,此時的one-to-many標(biāo)簽里不再像以前的one-to-one標(biāo)簽里用的是name屬性而是class屬性.
這兩個屬性的功能要分清楚.
單向一對多有缺點,因為要在一的一端維護(hù),所以多的一段的表里的外鍵字段不可設(shè)為非空.
而且要發(fā)出多余的update語句.一般都設(shè)為雙向的.下面來看雙向.
2 雙向
雙向配置的話class.hbm.xml不變,在student類里持有class類的引用,student.hbm.xml文件配置添加:
<many-to-one name="classes" column="classesid(必須和class.hbm.xml里的<key
column="classesid"/>一致)"/>
這樣配置就可以存儲.
有三種存儲方式.這是第一種.因為是一的一端維護(hù),所以多發(fā)兩條update.步驟是先挨個存student,再存
class.
第二種先存class,把classid字段存到student里,再挨個存student.也就是反轉(zhuǎn).class.hbm.xml里:
<set name="students" inverse="true">
第三種把classid字段存到student里,不存student.只存class. 也就是反轉(zhuǎn)并級聯(lián)操作.class.hbm.xml里
:<set name="students" inverse="true" cascade="all">
關(guān)于存儲上,基本上就這三種.無論是一對多還是多對一.個人認(rèn)為比較麻煩.具體應(yīng)用的時候可以考慮改進(jìn)
.
多對一的時候,因為站在多的立場,如果不級聯(lián),要先存一,把一的數(shù)據(jù)加到多里的引用,再存多.級聯(lián)了,因
為不用考慮一的關(guān)系,所以只存多.
而一對多的時候,反轉(zhuǎn)不級聯(lián),就站在多的立場.也要先存一再存多.反轉(zhuǎn)只是立場轉(zhuǎn)為多對一,所以同上.
反轉(zhuǎn)并級聯(lián),也同上.不考慮一.
不反轉(zhuǎn)也不級聯(lián),因為站在一的立場,就要先存多.把多加入到一的set集合,再存一.所以呢,立場和先存誰
是對立的.
請消化一下以上的總結(jié).
下面來看多對多.
四 多對多關(guān)聯(lián)映射(單雙向)
1 單向.
多對多涉及到第三方表.hibernate會自動生成.一般權(quán)限上會用到,比如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 class="com.bjsxt.hibernate.Role" column="roleid"/>
</set>
分析一下,set標(biāo)簽不用多說,table屬性是指讓hibernate自動建立第三方表名字叫"t_user_role",key標(biāo)簽
是指在此表中生成一個關(guān)聯(lián)到本類(user的)叫userid的字段,
<many-to-many>標(biāo)簽里class屬性引入類Role,并在t_user_role里生成一個關(guān)聯(lián)到role的roleid字段.
在t_user_role表里,userid和roleid一并叫做復(fù)合主鍵.因為兩者的聯(lián)合有不可重復(fù)性.
其存儲流程:1,存入role,2,用一個set集合接住role放到user的set里,(這里交叉存入比較容易看暈)3,挨
個存user.與上面的第二種存儲方案差不多.
Load時候就簡單,加載進(jìn)來,在user里用一個遍歷挨個從set里拿出來.就得到role表里的值.
執(zhí)行存入的時候,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 class="com.bjsxt.hibernate.User" column="userid"/>
</set>
注意兩類對比,保持column屬性值一致.
table屬性值必須和單向關(guān)聯(lián)中的table屬性值一致
<key>中column屬性值要與單向關(guān)聯(lián)中的<many-to-many>標(biāo)簽中的column屬性值一致
在<many-to-many>中的column屬性值要與單向關(guān)聯(lián)中<key>標(biāo)簽的column屬性值一致
order-by="userid"屬性是用來排序,按照t_user_role表的字段來排.
基本上,hibernate映射關(guān)系就是這些了