hibernate(四)[映射關(guān)系]

再開始本次知識點(diǎn)之前盏触,我們先來思考下get與load的區(qū)別。

  1. 對于Hibernate get方法,Hibernate會確認(rèn)一下該id對應(yīng)的數(shù)據(jù)是否存在晰筛,首先在session緩存中查找,然后在二級緩存中查找拴袭,還沒有就查詢數(shù)據(jù)庫读第,數(shù)據(jù) 庫中沒有就返回null。
  1. Hibernate load方法加載實(shí)體對象的時(shí)候拥刻,根據(jù)映射文件上類級別的lazy屬性的配置(默認(rèn)為true)怜瞒,分情況討論:

(1)若為true,則首先在Session緩存中查找,看看該id對應(yīng)的對象是否存在般哼,不存在則使用延遲加載吴汪,返回實(shí)體的代理類對象(該代理類為實(shí)體類的子類惠窄,由CGLIB動(dòng)態(tài)生成)。等到具體使用該對象(除獲取OID以外)的時(shí)候漾橙,再查詢二級緩存和數(shù)據(jù)庫杆融,若仍沒發(fā)現(xiàn)符合條件的記錄,則會拋出一個(gè)ObjectNotFoundException近刘。

(2)若為false,就跟Hibernateget方法查找順序一樣擒贸,只是最終若沒發(fā)現(xiàn)符合條件的記錄,則會拋出一個(gè)ObjectNotFoundException觉渴。

這里get和load有兩個(gè)重要區(qū)別:

如果未能發(fā)現(xiàn)符合條件的記錄介劫,Hibernate get方法返回null,而load方法會拋出一個(gè)ObjectNotFoundException案淋。

load方法可返回沒有加載實(shí)體數(shù)據(jù)的代 理類實(shí)例座韵,而get方法永遠(yuǎn)返回有實(shí)體數(shù)據(jù)的對象。

總之對于get和load的根本區(qū)別踢京,一句話誉碴,hibernate對于 load方法認(rèn)為該數(shù)據(jù)在數(shù)據(jù)庫中一定存在,可以放心的使用代理來延遲加載瓣距,如果在使用過程中發(fā)現(xiàn)了問題黔帕,只能拋異常;而對于get方 法蹈丸,hibernate一定要獲取到真實(shí)的數(shù)據(jù)成黄,否則返回null。


七種映射關(guān)系

hibernate在實(shí)現(xiàn)ORM功能的時(shí)候主要用到的文件有:映射類(.Java)逻杖、映射文件(.hbm.xml)和數(shù)據(jù)庫配置文件(.properties/.cfg.xml)奋岁,它們各自的作用如下。

映射類(*.java):它是描述數(shù)據(jù)庫表的結(jié)構(gòu)荸百,表中的字段在類中被描述成屬性闻伶,將來就可以實(shí)現(xiàn)把表中的記錄映射成為該類的對象了。

映射文件(*.hbm.xml):它是指定數(shù)據(jù)庫表和映射類之間的關(guān)系够话,包括映射類和數(shù)據(jù)庫表的對應(yīng)關(guān)系蓝翰、表字段和類屬性類型的對應(yīng)關(guān)系以及表字段和類屬性名稱的對應(yīng)關(guān)系等。

>    數(shù)據(jù)庫配置文件(*.properties/*.cfg.xml):它是指定與數(shù)據(jù)庫連接時(shí)需要的連接信息女嘲,比如連接哪種數(shù)據(jù)庫霎箍、登錄數(shù)據(jù)庫的用戶名、登錄密碼以及連接字符串等澡为。當(dāng)然還可以把映射類的地址映射信息放在這里。

接下來讓我們就一起走進(jìn)Hibernate的七種映射關(guān)系:

1景埃、 單向一對一關(guān)聯(lián)映射(one-to-one):

兩個(gè)對象之間一對一的關(guān)系媒至,例如:Person(人)-IdCard(身份證)
有兩種策略可以實(shí)現(xiàn)一對一的關(guān)聯(lián)映射:

主鍵關(guān)聯(lián):即讓兩個(gè)對象具有相同的主鍵值顶别,以表明它們之間的一一對應(yīng)的關(guān)系;數(shù)據(jù)庫表不會有額外的字段來維護(hù)它們之間的關(guān)系拒啰,僅通過表的主鍵來關(guān)聯(lián)驯绎。如下圖:

單向一對一主鍵關(guān)聯(lián)例子連接

唯一外鍵關(guān)聯(lián):外鍵關(guān)聯(lián),本來是用于多對一的配置谋旦,但是加上唯一的限制之后(采用<many-to-one>標(biāo)簽來映射剩失,指定多的一端unique為true,這樣就限制了多的一端的多重性為一)册着,也可以用來表示一對一關(guān)聯(lián)關(guān)系拴孤,其實(shí)它就是多對一的特殊情況。如下圖:

單向一對一唯一外鍵關(guān)聯(lián)例子連接

注意:因?yàn)橐粚σ坏闹麈I關(guān)聯(lián)映射擴(kuò)展性不好甲捏,當(dāng)我們的需要發(fā)生改變想要將其變?yōu)橐粚Χ嗟臅r(shí)候變無法操作了演熟,所以我們遇到一對一關(guān)聯(lián)的時(shí)候經(jīng)常會采用唯一外鍵關(guān)聯(lián)來解決問題,而很少使用一對一主鍵關(guān)聯(lián)司顿。


2芒粹、單向多對一關(guān)聯(lián)映射(many-to-one):

多對一關(guān)聯(lián)映射原理:在多的一端加入一個(gè)外鍵,指向一的一端大溜,如下圖:

單向多對一關(guān)聯(lián)映射

關(guān)鍵映射代碼——在多的一端加入如下標(biāo)簽映射:

<many-to-one name="group" column="groupid"/>  

3化漆、單向一對多關(guān)聯(lián)映射(one-to-many):

一對多關(guān)聯(lián)映射和多對一關(guān)聯(lián)映射原理是一致的,都是在多的一端加入一個(gè)外鍵钦奋,指向一的一端座云。如下圖(學(xué)生和班級):

單向一對多關(guān)聯(lián)映射

注意:它與多對一的區(qū)別是維護(hù)的關(guān)系不同

多對一維護(hù)的關(guān)系是:多指向一的關(guān)系,有了此關(guān)系锨苏,加載多的時(shí)候可以將一加載上來

一對多維護(hù)的關(guān)系是:一指向多的關(guān)系疙教,有了此關(guān)系,在加載一的時(shí)候可以將多加載上來

關(guān)鍵映射代碼——在一的一端加入如下標(biāo)簽映射:

<set name="students">  
      <key column="classesid"/>  
      <one-to-many class="com.hibernate.Student"/>  
</set>  

缺陷:因?yàn)槎嗟囊欢薙tudent不知道Classes的存在(也就是Student沒有維護(hù)與Classes的關(guān)系)所以在保存Student的時(shí)候關(guān)系字段classesid是為null的伞租,如果將該關(guān)系字段設(shè)置為非空贞谓,則將無法保存數(shù)據(jù),常用解決辦法是改用雙向關(guān)聯(lián)映射葵诈,參見6裸弦。


4、單向多對多映射(many-to-many):

多對多關(guān)聯(lián)映射新增加一張表才完成基本映射作喘,如下圖:

單向多對多映射

關(guān)鍵映射代碼——可以在User的一端加入如下標(biāo)簽映射:

<set name="roles" table="t_user_role">  
     <key column="user_id"/>  
     <many-to-many class="com.hibernate.Role" column="role_id"/>  
</set>  

5理疙、雙向一對一關(guān)聯(lián)映射:

對比單向一對一映射,需要在IdCard加入<one-to-one>標(biāo)簽泞坦,它不影響窖贤,只影響加載。如下圖:

雙向一對一關(guān)聯(lián)映射

雙向一對一主鍵映射關(guān)鍵映射代碼——在IdCard端新加入如下標(biāo)簽映射:

<one-to-one name="person"/>  

雙向一對一唯一外鍵映射關(guān)鍵映射代碼——在IdCard端新加入如下標(biāo)簽映射:

<one-to-one name="person"property-ref="idCard"/>  

注意:一對一唯一外鍵關(guān)聯(lián)雙向采用<one-to-one>標(biāo)簽映射,必須指定<one-to-one>標(biāo)簽中的property-ref屬性為關(guān)系字段的名稱


6赃梧、雙向一對多關(guān)聯(lián)映射(非常重要):

采用一對多雙向關(guān)聯(lián)映射的目的主要是為了主要是為了解決一對多單向關(guān)聯(lián)的缺陷而不是需求驅(qū)動(dòng)的滤蝠。

一對多雙向關(guān)聯(lián)的映射方式:

<li>在一的一端的集合上采用<key>標(biāo)簽,在多的一端加入一個(gè)外鍵

<li>在多的一端采用<many-to-one>標(biāo)簽

   >注意:<key>標(biāo)簽和<many-to-one>標(biāo)簽加入的字段保持一直授嘀,否則會產(chǎn)生數(shù)據(jù)混亂

  >關(guān)鍵映射代碼:

>  在Classes的一端加入如下標(biāo)簽映射:     
<set name="students"inverse="true">  
       <key column="classesid"/>  
      <one-to-many class="com.hibernate.Student"/>  
</set>  

在Student的一端加入如下標(biāo)簽映射:

<many-to-one name="classes" column="classesid"/>  

注釋:inverse屬性

<li> inverse屬性可以用在一對多和多對多雙向關(guān)聯(lián)上物咳,inverse屬性默認(rèn)為false,為false表示本端可以維護(hù)關(guān)系蹄皱,如果inverse為true览闰,則本端不能維護(hù)關(guān)系,會交給另一端維護(hù)關(guān)系巷折,本端失效压鉴。所以一對多關(guān)聯(lián)映射我們通常在多的一端維護(hù)關(guān)系,讓一的一端失效盔几。

<li> inverse是控制方向上的反轉(zhuǎn)晴弃,只影響存儲


7、雙向多對多關(guān)聯(lián)映射:

雙向的目的就是為了兩端都能將對方加載上來逊拍,和單向多對多的區(qū)別就是雙向需要在兩端都加入標(biāo)簽映射上鞠,需要注意的是:

<li>生成的中間表名稱必須一樣

<li>生成的中間表中的字段必須一樣

Role(角色)端關(guān)鍵映射代碼:

<set name="users" table="t_user_role">  
       <key column="role_id"/>  
       <many-to-many class="com.hibernate.User" column="user_id"/>  
lt;/set>  

User(用戶)端關(guān)鍵映射代碼:

<set name="roles" table="t_user_role">  
      <key column="user_id"/>  
      <many-to-many class="com. hibernate.Role" column="role_id"/>  
lt;/set>  

總結(jié):對于上面這七種關(guān)聯(lián)映射中,最重要的就是一對多的映射芯丧,因?yàn)樗N近我們的現(xiàn)實(shí)生活芍阎,比如:教室和學(xué)生就可以是典型的一對多的關(guān)系,而我們開發(fā)軟件的目的之一就是為了解決一些生活中重復(fù)性問題缨恒,把那些重復(fù)的問題交給計(jì)算機(jī)幫助我們完成谴咸,從而來提高我們的工作效率。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末骗露,一起剝皮案震驚了整個(gè)濱河市岭佳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌萧锉,老刑警劉巖珊随,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柿隙,居然都是意外死亡叶洞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門禀崖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衩辟,“玉大人,你說我怎么就攤上這事波附∫涨纾” “怎么了昼钻?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長财饥。 經(jīng)常有香客問我换吧,道長,這世上最難降的妖魔是什么钥星? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮满着,結(jié)果婚禮上谦炒,老公的妹妹穿的比我還像新娘。我一直安慰自己风喇,他們只是感情好宁改,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著魂莫,像睡著了一般还蹲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耙考,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天谜喊,我揣著相機(jī)與錄音,去河邊找鬼倦始。 笑死斗遏,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鞋邑。 我是一名探鬼主播诵次,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼枚碗!你這毒婦竟也來了逾一?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肮雨,失蹤者是張志新(化名)和其女友劉穎遵堵,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酷含,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鄙早,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了椅亚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片限番。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖呀舔,靈堂內(nèi)的尸體忽然破棺而出弥虐,到底是詐尸還是另有隱情扩灯,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布霜瘪,位于F島的核電站珠插,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏颖对。R本人自食惡果不足惜捻撑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缤底。 院中可真熱鬧顾患,春花似錦、人聲如沸个唧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽徙歼。三九已至犁河,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間魄梯,已是汗流浹背桨螺。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留画恰,地道東北人彭谁。 一個(gè)月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像允扇,于是被迫代替她去往敵國和親缠局。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 作為一種輕量級的關(guān)系映射工具考润,Hibernate支持各種關(guān)系映射狭园,例如:多對一、一對多和一對一的數(shù)據(jù)庫表關(guān)系糊治,通過...
    Ystrator閱讀 532評論 0 1
  • 上篇文章我們對持久化對象進(jìn)行的學(xué)習(xí)唱矛,了解了它的三種不同的狀態(tài)并通過它完成對數(shù)據(jù)庫的映射操作。但這都是基于單張表的操...
    Single_YAM閱讀 498評論 0 1
  • 本文包括:1井辜、一對多結(jié)構(gòu)的準(zhǔn)備2绎谦、雙向關(guān)聯(lián)與單向關(guān)聯(lián)3、級聯(lián)保存4粥脚、級聯(lián)刪除5窃肠、cascade 屬性——級聯(lián)6、i...
    廖少少閱讀 1,227評論 1 6
  • 認(rèn)識hibernate的幾種映射關(guān)系: 單向1-1(與單向N-1相似)例子:一個(gè)人擁有一個(gè)身份證有兩種策略實(shí)現(xiàn)1-...
    莫失莫忘解我憂傷閱讀 392評論 0 1
  • 一.單向一對多的關(guān)聯(lián) 通過在 一 方使用 元素標(biāo)識 多的對象;班級對象代表一, 學(xué)生對象代表多數(shù)據(jù)結(jié)構(gòu)中班級表學(xué)生...
    liangxifeng833閱讀 450評論 0 0