我們還用上篇博客中貼的圖。在Hibernate中有如下7中關聯映射。
上篇博客已經將一對一的兩種映射類型及不同的實現策略介紹完了。本篇博客繼續討論關聯映射中的多對一映射。
一對多關聯映射
一)單向多對一關聯映射
舉例:,用戶和組是多對一的關係。一個組有多個用戶,一個用戶只屬於一個組。
實現策略:有了ER圖知識的積累,我們知道多對一的關聯映射策略一定是在多的一端加入一個外鍵,指向一的一端。
關鍵代碼:在多的一端加入標籤映射。
<hibernate-mapping>
<classname="com.bjpowernode.hibernate.User"table="t_user">
<idname="id">
<generatorclass="native"/>
</id>
<propertyname="name"/>
<many-to-one name="group"column="groupid"cascade="save-update"/>
</class>
</hibernate-mapping>
備註
cascade級聯,意思是指定兩個對象之間的操作聯動關係,對一個對象執行了操作(他是對象之間的連鎖操作,隻影響添加,刪除和修改。)之後,對其指定的級聯對象也需要執行相同的操作。可以取值爲all,none,save-update,delete。all代表在所有的情況下都執行級聯操作。none指在所有情況下都不執行級聯操作。save-update指在保存和更新的時候執行級聯操作。delete指在刪除的時候執行級聯操作。
二)單向一對多關聯映射
舉例 : 班級和學生是一對多的關係。一個班級有多個學生,一個學生只能屬於一個班。
實現策略:在多的一端加入一一端的主鍵當做外鍵。這樣的冗餘是最少的。
關鍵代碼 : 在一的一端加入標籤映射。
<hibernate-mapping>
<classname="com.bjpowernode.hibernate.Group"table="t_group">
<idname="id">
<generatorclass="native"/>
</id>
<propertyname="name"/>
<set name=”users”>
<key column=”groupId”/>
<one-to-many class="com.bjpowernode.hibernate.User">
</set>
</class>
</hibernate-mapping>
這是多對一的映射。
備註:
上面我們採用的是在一的一端維護關係。這樣的話,多的一端並不知道一的一端的存在。也就是說學生並不知道班級的存在。從代碼層級上考慮,在保存學生的時候,關係字段classid是爲null的。如果將該字段設置爲非空,就不能保存數據了。另外,又由於student並不維護關係,class維護關係,則在對class進行操作時,class就會發出多餘的update語句,去維護group與user的關係。可見一對多關聯映射存在很大問題。
那麼要解決這個問題,我們就要看一下面的一對多雙向關聯。
三)雙向一對多關聯映射(重要):
該映射主要是爲了解決一對多單向關聯的缺陷,並非業務需求導致的。
映射策略:在一的一端的集合上採用標籤,並用標籤。在多的一端加入一個外鍵,同時在多的一端採用標籤。
主要代碼:
student(多的一端)
<many-to-one name="classes" column="classesid"/>
classes(一的一端)
<set name="students"inverse="true">
<key column="classesid"/>
<one-to-many class="com.hibernate.Student"/>
</set>
備註:
其中inverse屬性可以用在一對多和多對多雙向關聯上,inverse屬性默認爲false,爲false表示本端可以維護關係,如果inverse爲true,則本端不能維護關係,會交給另一端維護關係,本端失效。所以一對多關聯映射我們通常在多的一端維護關係,讓一的一端失效。inverse是控制方向上的反轉,隻影響存儲。
總結:
本篇博客介紹了多對一的三種映射關係及其實現策略。包括一對多單向,多對一單項,和一對多雙向映射。那麼一對多單向映射和多對一的單向映射來說,他們最大的不同是維護的關係不同。
多對一單向維護的是:多指向一的關係,加載多的時候可以將一一起加載上來。
一對多單向維護的是:一指向多的關係,在加載醫德時候可以將多加載上來。
一對多雙向(也是多對一雙向)映射也是爲了解決多對一的加載和保存的問題而出現的,在項目開發中,這種雙向映射也是非常普遍應用的。
下篇博客中我們繼續介紹關聯映射之多對多映射。