hibernate(四)[映射關系]

再開始本次知識點之前,我們先來思考下get與load的區別。

  1. 對于Hibernate get方法,Hibernate會確認一下該id對應的數據是否存在,首先在session緩存中查找,然后在二級緩存中查找,還沒有就查詢數據庫,數據 庫中沒有就返回null。
  1. Hibernate load方法加載實體對象的時候,根據映射文件上類級別的lazy屬性的配置(默認為true),分情況討論:

(1)若為true,則首先在Session緩存中查找,看看該id對應的對象是否存在,不存在則使用延遲加載,返回實體的代理類對象(該代理類為實體類的子類,由CGLIB動態生成)。等到具體使用該對象(除獲取OID以外)的時候,再查詢二級緩存和數據庫,若仍沒發現符合條件的記錄,則會拋出一個ObjectNotFoundException。

(2)若為false,就跟Hibernateget方法查找順序一樣,只是最終若沒發現符合條件的記錄,則會拋出一個ObjectNotFoundException。

這里get和load有兩個重要區別:

如果未能發現符合條件的記錄,Hibernate get方法返回null,而load方法會拋出一個ObjectNotFoundException。

load方法可返回沒有加載實體數據的代 理類實例,而get方法永遠返回有實體數據的對象。

總之對于get和load的根本區別,一句話,hibernate對于 load方法認為該數據在數據庫中一定存在,可以放心的使用代理來延遲加載,如果在使用過程中發現了問題,只能拋異常;而對于get方 法,hibernate一定要獲取到真實的數據,否則返回null。


七種映射關系

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

映射類(*.java):它是描述數據庫表的結構,表中的字段在類中被描述成屬性,將來就可以實現把表中的記錄映射成為該類的對象了。

映射文件(*.hbm.xml):它是指定數據庫表和映射類之間的關系,包括映射類和數據庫表的對應關系、表字段和類屬性類型的對應關系以及表字段和類屬性名稱的對應關系等。

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

接下來讓我們就一起走進Hibernate的七種映射關系:

1、 單向一對一關聯映射(one-to-one):

兩個對象之間一對一的關系,例如:Person(人)-IdCard(身份證)
有兩種策略可以實現一對一的關聯映射:

主鍵關聯:即讓兩個對象具有相同的主鍵值,以表明它們之間的一一對應的關系;數據庫表不會有額外的字段來維護它們之間的關系,僅通過表的主鍵來關聯。如下圖:

單向一對一主鍵關聯例子連接

唯一外鍵關聯:外鍵關聯,本來是用于多對一的配置,但是加上唯一的限制之后(采用<many-to-one>標簽來映射,指定多的一端unique為true,這樣就限制了多的一端的多重性為一),也可以用來表示一對一關聯關系,其實它就是多對一的特殊情況。如下圖:

單向一對一唯一外鍵關聯例子連接

注意:因為一對一的主鍵關聯映射擴展性不好,當我們的需要發生改變想要將其變為一對多的時候變無法操作了,所以我們遇到一對一關聯的時候經常會采用唯一外鍵關聯來解決問題,而很少使用一對一主鍵關聯。


2、單向多對一關聯映射(many-to-one):

多對一關聯映射原理:在多的一端加入一個外鍵,指向一的一端,如下圖:

單向多對一關聯映射

關鍵映射代碼——在多的一端加入如下標簽映射:

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

3、單向一對多關聯映射(one-to-many):

一對多關聯映射和多對一關聯映射原理是一致的,都是在多的一端加入一個外鍵,指向一的一端。如下圖(學生和班級):

單向一對多關聯映射

注意:它與多對一的區別是維護的關系不同

多對一維護的關系是:多指向一的關系,有了此關系,加載多的時候可以將一加載上來

一對多維護的關系是:一指向多的關系,有了此關系,在加載一的時候可以將多加載上來

關鍵映射代碼——在一的一端加入如下標簽映射:

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

缺陷:因為多的一端Student不知道Classes的存在(也就是Student沒有維護與Classes的關系)所以在保存Student的時候關系字段classesid是為null的,如果將該關系字段設置為非空,則將無法保存數據,常用解決辦法是改用雙向關聯映射,參見6。


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

多對多關聯映射新增加一張表才完成基本映射,如下圖:

單向多對多映射

關鍵映射代碼——可以在User的一端加入如下標簽映射:

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

5、雙向一對一關聯映射:

對比單向一對一映射,需要在IdCard加入<one-to-one>標簽,它不影響,只影響加載。如下圖:

雙向一對一關聯映射

雙向一對一主鍵映射關鍵映射代碼——在IdCard端新加入如下標簽映射:

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

雙向一對一唯一外鍵映射關鍵映射代碼——在IdCard端新加入如下標簽映射:

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

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


6、雙向一對多關聯映射(非常重要):

采用一對多雙向關聯映射的目的主要是為了主要是為了解決一對多單向關聯的缺陷而不是需求驅動的。

一對多雙向關聯的映射方式:

<li>在一的一端的集合上采用<key>標簽,在多的一端加入一個外鍵

<li>在多的一端采用<many-to-one>標簽

   >注意:<key>標簽和<many-to-one>標簽加入的字段保持一直,否則會產生數據混亂

  >關鍵映射代碼:

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

在Student的一端加入如下標簽映射:

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

注釋:inverse屬性

<li> inverse屬性可以用在一對多和多對多雙向關聯上,inverse屬性默認為false,為false表示本端可以維護關系,如果inverse為true,則本端不能維護關系,會交給另一端維護關系,本端失效。所以一對多關聯映射我們通常在多的一端維護關系,讓一的一端失效。

<li> inverse是控制方向上的反轉,只影響存儲


7、雙向多對多關聯映射:

雙向的目的就是為了兩端都能將對方加載上來,和單向多對多的區別就是雙向需要在兩端都加入標簽映射,需要注意的是:

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

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

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

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

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

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

總結:對于上面這七種關聯映射中,最重要的就是一對多的映射,因為它更貼近我們的現實生活,比如:教室和學生就可以是典型的一對多的關系,而我們開發軟件的目的之一就是為了解決一些生活中重復性問題,把那些重復的問題交給計算機幫助我們完成,從而來提高我們的工作效率。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,489評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,290評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,776評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,510評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,866評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,036評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,585評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,331評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,536評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,754評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,154評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,469評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,273評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,505評論 2 379

推薦閱讀更多精彩內容

  • 作為一種輕量級的關系映射工具,Hibernate支持各種關系映射,例如:多對一、一對多和一對一的數據庫表關系,通過...
    Ystrator閱讀 537評論 0 1
  • 上篇文章我們對持久化對象進行的學習,了解了它的三種不同的狀態并通過它完成對數據庫的映射操作。但這都是基于單張表的操...
    Single_YAM閱讀 511評論 0 1
  • 本文包括:1、一對多結構的準備2、雙向關聯與單向關聯3、級聯保存4、級聯刪除5、cascade 屬性——級聯6、i...
    廖少少閱讀 1,232評論 1 6
  • 認識hibernate的幾種映射關系: 單向1-1(與單向N-1相似)例子:一個人擁有一個身份證有兩種策略實現1-...
    莫失莫忘解我憂傷閱讀 393評論 0 1
  • 一.單向一對多的關聯 通過在 一 方使用 元素標識 多的對象;班級對象代表一, 學生對象代表多數據結構中班級表學生...
    liangxifeng833閱讀 458評論 0 0