【Hibernate步步为营】--关联映射之多对一
一、關(guān)聯(lián)映射之多對(duì)一
??????? 對(duì)于多對(duì)一關(guān)聯(lián)映射其實(shí)很容易理解,在思考時(shí)可以把它看做人員和組之間的關(guān)系,在一個(gè)組中會(huì)有多個(gè)人員,所以這就出現(xiàn)了多對(duì)一的關(guān)系多個(gè)人會(huì)同屬于一個(gè)組,那么在設(shè)計(jì)關(guān)系模型時(shí)就會(huì)有兩種設(shè)計(jì)方法,一種是將組號(hào)作為外鍵添加到用戶表中,另外一種是單獨(dú)生成第三張表,將用戶id號(hào)和組id號(hào)相關(guān)聯(lián)。對(duì)于第一種設(shè)計(jì)方法它的關(guān)系模型可用下表表示:
?????? 這種多對(duì)一關(guān)聯(lián)映射反應(yīng)到對(duì)象模型中它是一種聚合關(guān)系,User是group的一部分,group中存在User,它們兩個(gè)的生命周期是不相同的,可反應(yīng)為下圖:
????? 那么這種多對(duì)一關(guān)系映射在Hibernate中是如何設(shè)置的呢?下面將會(huì)介紹兩種方法,使用<many-to-one>標(biāo)簽直接映射,或者使用<many-to-one>的cascade級(jí)聯(lián)修改表。
? 1、Many-to-one直接映射
?????? 從字面意思上就能夠理解,它是指多對(duì)一的關(guān)系,many指的是多的一端,one指的是少的一端,在使用時(shí)往往在多的一端的hbm中使用該標(biāo)簽,并將<many-to-one>的name屬性設(shè)置為該映射文件對(duì)應(yīng)的類中的one一端的屬性,如:<many-to-one name="group" column="groupid"></many-to-one>,該標(biāo)簽添加在了User.hbm.xml中,它對(duì)應(yīng)many;標(biāo)簽中的name值為group對(duì)映射one,并且在User.java中會(huì)有一個(gè)名為group的屬性。接下來(lái)看下具體實(shí)現(xiàn)實(shí)現(xiàn)的代碼類。
??? (1)User.java類代碼,其中有一個(gè)名為group的屬性,它將會(huì)作為<many-to-one>的one一端的name值。
?????? (2)User.hbm.xml中的<many-to-one>,name的值為User.java中one端的屬性值,它會(huì)在數(shù)據(jù)庫(kù)中生成一個(gè)新列,可以將該新列理解為User表的外鍵。
[html] view plain copy
???? (3)測(cè)試上面的映射關(guān)系,向表中寫(xiě)入兩個(gè)User對(duì)象分別為user1和user2,命名為張三和李四,使用session保存對(duì)象,向數(shù)據(jù)庫(kù)中寫(xiě)入數(shù)據(jù),代碼如下:
[java] view plain copy
??????? 但是使用上面的代碼在執(zhí)行寫(xiě)入時(shí)會(huì)報(bào)錯(cuò)TransientObjectException,這是因?yàn)樵诒4鎁ser對(duì)象時(shí)它會(huì)按照<many-to-one>中添加的group去內(nèi)存中查找group對(duì)象,但是上面的代碼中g(shù)roup對(duì)象一直都是在Transient狀態(tài)中,并沒(méi)有被session管理,也就是說(shuō)查找不到session對(duì)象,而User對(duì)象進(jìn)入了Persistent狀態(tài),于是會(huì)報(bào)此錯(cuò)誤。正確的代碼如下:
[java] view plain copy
? 2、級(jí)聯(lián)映射
???????? 除了上面所說(shuō)的將group對(duì)象和user對(duì)象都轉(zhuǎn)化到Persistent對(duì)象外,還可以使用cascade級(jí)聯(lián)映射屬性,在<many-to-one>屬性中添加cascade屬性,并復(fù)制為save-update,在group對(duì)象并非為Persistent狀態(tài)時(shí)即可寫(xiě)入數(shù)據(jù)庫(kù)。這樣只需要將兩個(gè)user對(duì)象的Group屬性設(shè)置為同一個(gè)group對(duì)象即可實(shí)現(xiàn)多對(duì)一的映射關(guān)系,此時(shí)User.hbm.xml中對(duì)應(yīng)的內(nèi)容為如下代碼:
??? ?? Note:cascade設(shè)置為save-update后即可實(shí)現(xiàn)向數(shù)據(jù)庫(kù)中級(jí)聯(lián)修改、添加和刪除,但是具體的級(jí)聯(lián)查詢操作卻不可以。
?????? 對(duì)應(yīng)的測(cè)試配置文件的方法為如下代碼:
[java] view plain copy
? 3、對(duì)比升華
??????? 兩種方法同樣實(shí)現(xiàn)了多對(duì)一的映射方法,結(jié)果上是相同的,但在實(shí)現(xiàn)上很不相同。無(wú)論是第一種還是第二種采用的都是<many-to-one>在many一端的映射文件中添加該標(biāo)簽,并將標(biāo)簽的name屬性賦值為該映射文件注冊(cè)的類中的one一端的屬性值,這樣就完成了多對(duì)一的基本映射,這是相同點(diǎn)。不同點(diǎn)是直接映射關(guān)系沒(méi)有采用Hibernate字段的屬性,這樣在實(shí)現(xiàn)上較靈活,不但支持增刪改,而且可以查詢;第二種的cascade級(jí)聯(lián)修改則采用了Hibernate提供的方法,此種方法只支持增刪改,并不支持查詢。
結(jié)語(yǔ)
???????
?????? 文章介紹了兩種方法來(lái)實(shí)現(xiàn)多對(duì)一的映射,這兩種方法在實(shí)現(xiàn)結(jié)果上是相同的,都是采用的<many-to-one>多對(duì)一標(biāo)簽,實(shí)現(xiàn)上很簡(jiǎn)單。需要注意的是第一種方法必須將組對(duì)象和用戶全部轉(zhuǎn)化為T(mén)ransient狀態(tài),都必須被Session管理這樣在保存時(shí)才能夠在Session中查找到兩種對(duì)象。多對(duì)一映射是經(jīng)常使用的,另外還有其它的映射關(guān)系,將會(huì)在下篇文章中討論。
總結(jié)
以上是生活随笔為你收集整理的【Hibernate步步为营】--关联映射之多对一的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Hibernate步步为营】--多对多
- 下一篇: Spring的AOP使用xml配置