一對一關聯分爲主鍵關聯與外鍵關聯。
主鍵關聯:不必加額外的字段,只是主表和輔表的主鍵相關聯,即這兩個主鍵的值是一樣的。
外鍵關聯:輔表有一個額外的字段和主表相關聯,或者兩個表都有額外的字段與對應表的相關聯。
一、xml文件配置
官方文檔解釋
<one-to-one
name="propertyName" (1)
class="ClassName" (2)
cascade="cascade_style" (3)
constrained="true|false" (4)
fetch="join|select" (5)
property-ref="propertyNameFromAssociatedClass" (6)
access="field|property|ClassName" (7)
formula="any SQL expression" (8)
lazy="proxy|no-proxy|false" (9)
entity-name="EntityName" (10)
node="element-name|@attribute-name|element/@attribute|."
embed-xml="true|false"
foreign-key="foreign_key_name"
/>
(1) name: 屬性的名字。
(2) class (可選 - 默認是通過反射得到的屬性類型):被關聯的類的名字。
(3) cascade(級聯) (可選):表明操作是否從父對象級聯到被關聯的對象。
(4) constrained(約束) (可選):表明該類對應的表對應的數據庫表,和被關聯的對象所對應的數據庫表之間,通過一個外鍵引用對主鍵進行約束。 這個選項影響save()和delete()在級聯執行時的先後順序以及 決定該關聯能否被委託(也在schema export tool中被使用).
(5) fetch (可選 - 默認設置爲選擇): 在外連接抓取或者序列選擇抓取選擇其一.
(6) property-ref (可選):指定關聯類的屬性名,這個屬性將會和本類的主鍵相對應。如果沒有指定,會使用對方關聯類的主鍵。
(7) access (可選 - 默認是 property): Hibernate用來訪問屬性的策略。
(8) formula (可選):絕大多數一對一的關聯都指向其實體的主鍵。在一些少見的情況中, 你可能會指向其他的一個或多個字段,或者是一個表達式,這些情況下,你可以用一個SQL公式來表示。 (可以在org.hibernate.test.onetooneformula找到例子)
(9) lazy (可選 - 默認爲 proxy): 默認情況下,單點關聯是經過代理的。lazy="no-proxy"指定此屬性應該在實例變量第一次被訪問時應該延遲抓取(fetche lazily)(需要運行時字節碼的增強)。 lazy="false"指定此關聯總是被預先抓取。注意,如果constrained="false", 不可能使用代理,Hibernate會採取預先抓取!
(10) entity-name (可選): 被關聯的類的實體名。
1. 主鍵關聯
唯一外鍵關聯:
例: User和Account,一個用戶對應一個賬戶。
配置文件都用one-to-one,在輔表的one-to-one的屬性裏要加constrained="true"表示受到約束。所以,將輔表的id改成foreign然後加上屬性參數等。
User
Account
User類與配置文件
private Integer id;
private String username;
private String password;
private Account account;
one-to-one中的class屬性可以不寫,默認Hibernate會使用反正自己去尋找。
<one-to-one name="account" class="piaohan.domain.Account"cascade="all" />
Account類與配置
private Integer id;
private String accountNum;
private Integer money;
private User user;
<id name="id" column="id">
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<one-to-one name="user" constrained="true"
class="piaohan.domain.User">
</one-to-one>
constrained="true"表示這個屬性(name="user")對應類型的表(user表),對我現在的表(account表)形成了外鍵約束,user表的主鍵對account表的主鍵形成了外鍵約束。
該種方式如果刪除想刪除user對象中的account對象,不能直接刪除account,需要先刪除雙方關係,如user.setAccount(null);或者在account方加上cascade。
2. 單方外鍵關聯
例: User和Account,一個用戶對應一個賬戶。
User
Account
這種關聯Account是用many-to-one然後用unique="true"做限制,限制成一對一的關係。所以,一對一的外鍵關聯其實就是多對一關聯的一種特例。
User類與配置
private Integer id;
private String username;
private String password;
private Account account;
<one-to-one name="account" class="piaohan.domain.Account"
cascade="all" property-ref="user" />
property-ref="user" 表示關聯類的屬性名,即對應類的保存本類的屬性名,該例在User中,表示對應類Account中,保存User屬性的屬性名,即user。
Account類與配置
private Integer id;
private String accountNum;
private Integer money;
private User user;
<many-to-one name="user" unique="true" column="userid" />
3. 雙方外鍵關聯
如果關聯雙方都是外鍵關聯,那可以兩邊都用many-to-one。
User配置(類不變)
<many-to-one name="account" cascade="all" unique="true"
column="accountid" />
Account配置(類不變)
<many-to-one name="user" unique="true" column="userid"
cascade="all" />