關系映射之間的關系是講對象之間的關系,並不指數據庫表的關系(外鍵關系),下面逐一分析解釋。
多對一關聯映射(User—->Group)
原理:在多的一端加入一個外鍵,指向一的一端。
舉例:多個用戶(User)屬於某個用戶組(Group)。
User對象的映射文件User.hbm.xml。
[html]
<hibernate-mapping>
<class name="com.snail.hibernate.User" table="t_user">
<id name="id" column="user_id">
<generator class="native"/>
</id>
<property name="name" length="30" unique="true" not-null="true"/>
<many-to-one name="group" column="groupid" cascade="save-update"/>
</class>
</hibernate-mapping>
這是最常用的映射關系,在對象模型中是User對象持有Group對象的一個引用,在具體配置中, 多的一端(User)用<many-to-one>標簽加入關聯對象(Group)的主鍵(groupid)。cascade(級聯)意思是指定兩個對象之間的操作聯動關系,對一個對象執行瞭操作後,對其指定的級聯對象也需要執行相同的操作。如果不設置上面cascade的save-update屬性,那麼必須在每個瞬時對象後顯示調用save或update方法,否則將拋出org.hibernate.TransientObjectException異常。
一對多關聯映射(單向Classes—->Student)
原理:一對多關聯映射和多對一關聯映射原理一致,不同在於:多對一維護的關系是在加載多的一端時可以將一加載上來;一對多可以在加載一時將多加載上來。
舉例:某個班級(Classes)有多位學生(Student)。
一的一端Classes的映射文件Classes.hbm.xml。
[html] view plaincopy
<hibernate-mapping package="com.snail.hibernate">
<class name="Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students">
<key column="classesid"/>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
在對象模型中,一的一端(Classes)以集合Set的方式持有Student的引用(private Set students),在具體配置中,<set> 元素用來映射Set類型的屬性,除瞭<set>,還有<list>, <map>, <bag>, <array> 和 <primitive-array> 映射元素,寫完<set>元素後,必須指明裡面放什麼內容,在一的一端使用<key>標簽,在多的一端加入一個外鍵,將兩個對象建立連接。<one-to-many>指明set內放入的是Student對象。
在一的一端維護關系存在缺陷:
* 因為多的一端Student不知道Classes的存在(也就是Student沒有維護與Classes的關系),所以在保存Student的時候關系字段classesid是為null的,如果將該關系字段設置為非空,則將無法保存數據。
* 另外因為Student不維護關系,而Classes維護關系,Classes就會發出多餘的update語句,保證Classes和Student有關系,這樣加載Classes的時候才可以把該Classes對應的學生加載上來。
一對多關聯映射(雙向Classes<—->Student)
原理:采用一對多雙向關聯映射的目的主要是為瞭主要是為瞭解決一對多單向關聯的缺陷,而不是需求驅動的。
舉例:同上例。
一的一端Classes映射文件Classes.hbm.xml。
[html]
<hibernate-mapping package="com.snail.hibernate">
<class name="Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students" inverse="true">
<key column="classesid"/>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
多的一端Student的映射文件Student.hbm.xml。
[html] view plaincopy
<hibernate-mapping package="com.snail.hibernate">
<class name="Student" table="t_student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="classes" column="classesid"/>
</class>
</hibernate-mapping>
這兩個配置文件和上面介紹的映射關系相同,不多做介紹。值得註意的是Classes.hbm.xml中inverse屬性,inverse屬性可以用在一對多和多對多雙向關聯上,inverse屬性默認為false,為false表示本端可以維護關系,如果inverse為true,則本端不能維護關系,會交給另一端維護關系,本端失效,所以一對多關聯映射我們通常在多的一端維護關系,讓一的一端失效,所以設置為inverse為true。
inverse和cascade的區別
* inverse是控制方向上的反轉,隻影響存儲
* cascade是操作上的連鎖反映
作者:StubbornPotatoes