一對一關聯關係(基於外鍵映射和基於主鍵映射兩種方式)

終於講到了一對一的關聯關係,好了,不用再講年級和學生的“故事”了。我們來講講經理和部門的故事吧。

現在存在兩個這樣的持久化類:

Manager:

public class Manager {
	private int mgrId;
	private String mgrName;
	private Department department;
	// 省略構造方法和set、get方法....
}

 

Department:

public class Department {
	private int depId;
	private String depName;
	private Manager manager;
	// 省略構造方法和set、get方法....
}

 

 

 

一、基於外鍵映射的一對一關聯關係

老套路了,配置hbm文件。配置之前,我們先討論一個問題,在這個關係中外鍵保存在Manager或者Department對應的數據表中是不是都可以?理論上講是這樣的,我們今天就將外鍵設置在Department對應的數據表中。設置外鍵用什麼,大家也想一想,我們在之前的映射中存在外鍵的數據表在hbm文件中都配置了什麼?是不是many-to-one標籤?不要看字面意思就認爲它只能用於多對一的映射,那太狹隘了。只要可以設置外鍵的地方都可以使用這個標籤。至於限制一對一,可以添加unique唯一約束。就像下面的代碼:

<many-to-one name="manager" class="Manager" column="ManagerId" unique="true"></many-to-one>

 

Manager的配置則如下:

<one-to-one name="department"  class="Department" property-ref="manager"></one-to-one>

 

property-ref需要講一下,這是指定一對一關係的另外一個持久化類的外鍵對應的那個屬性。翻譯一下就是Department對應的數據表中的外鍵ManagerId對應的那個持久化類中的屬性,也就是manager。有點繞,理一理還是不難理解的。如果不配置這個屬性,則Manager默認參考的是Department的主鍵。

好了,至於方法的測試也沒什麼好講的。但是事到如今,我們來小小的總結下開發中需要注意的問題。存在外鍵的持久化類和不存在外鍵的持久化類的區別。在上面的一對一關係中,Department存在外鍵。在查詢的時候,如果查詢Manager會一次性將所有的信息包括Department的數據一起查詢出來,但是查詢Department則會出現延遲加載(懶加載),所以後者會出現懶加載異常。保存操作時,先保存無外鍵的持久化類對象則會使得整個保存操作少update語句。

 

二、基於主鍵映射的一對一關聯關係

配置hbm文件時,Manager的配置保持不變,只需要更改Department的配置即可。基於主鍵的映射,什麼意思?主鍵怎麼映射呢?我們可以讓Department的主鍵生成參考Manager的主鍵可以嗎?當然可以,Hibernate也支持這樣做。基於主鍵的映射策略:指一端的主鍵生成器使用 foreign 策略,表明根據”對方”的主鍵來生成自己的主鍵,自己並不能獨立生成主鍵. 然後使用<param> 子元素指定使用當前持久化類的哪個屬性作爲 “對方”。像下面這樣:

  <id name="depId" type="int">
            <column name="DEPID" />
            <!-- 使用外鍵的方式來生成當前的主鍵 -->
            <generator class="foreign" >
            	<!-- property屬性指定使用當前持久化類的哪一個屬性(也是一個持久化類)的主鍵作爲外鍵 -->
             	<param name="property">manager</param>
            </generator>
    </id>

 

需要注意的是:採用foreign主鍵生成器策略的一端增加 one-to-one 元素映射關聯屬性,其one-to-one屬性還應增加constrained=“true” 屬性。constrained(約束):指定爲當前持久化類對應的數據庫表的主鍵添加一個外鍵約束,引用被關聯的對象(“對方”)所對應的數據庫表主鍵,所以Department一端的one-to-one配置如下:

<one-to-one name="manager" class="Manager" constrained="true"></one-to-one>

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章