Nhibernate 一對一,一對多,多對多 成功映射


前語:

在Nhibernate xml 的文件配置上,一對一和多對多的配置比較簡單,容易出錯的反而是一對多(多對一)上。

1、一對一關聯關系的映射:

<one-to-one
                name="propertyName"
                class="ClassName"
                cascade="cascade_style"
                constrained="true|false"
                fetch="join|select" 
                property-ref="propertyNameFromAssociatedClass"
                access="field|property|ClassName"
                formula="any sql expression"
                lazy="true|proxy|false"
                entity-name="EntityName"
                node="element-name|@attribute-name|element/@attribute|."
                embed-xml="true|false"
/>    
序號 屬性 含義和作用 必須 默認值
1
name
映射類屬性的名字 Y  
2
class
映射的目標類。也就是與這個屬性相關聯的是哪個類 N  
3
cascade

操作時的級聯關系 。這個屬性的可選值有:

  all--所有的操作均進行級聯操作。

  none--所有操作均不進行級聯操作

  save-update--在執行 save 和 update 時進行級聯操作

  delete--在執行delete時進行級聯操作

N  
4
constrained
表明當前類對應的表與被關聯的表之間是否存在着外鍵約束。這將影響級聯操作的順序 N false
5
fetch

設置抓取數據的策略。這個屬性的可選值有:

  join--外連接抓取

  select--序列選擇抓取

N  
6
property-ref
指定關聯類的屬性名,這個屬性將會和本類的主鍵相對應 N 關鍵類的主鍵
7
access
Hibernate 訪問這個屬性的策略 N property
8
formula

絕大多數一對一的關聯都指向其實體的主鍵。在一些少見的情況中,可能會指向其他的

一個或多個字段,或者是一個表達式,在這些情況下,可以用一個sql公式來表示

N  
9
lazy

指定對於此關聯對象是否使用延遲加載的策略。這個屬性的可選值有:

  proxy--通過代理進行關聯

  true--此關聯對象采用延遲加載,在該實例變量第一次被訪問時抓取(需要運行時

字節翃的增強)

  false--此關聯對象不采用延遲加載。注意,如果constrained="false",則不能

使用代理,hibernate會采取預先抓取

N proxy
10
entity-name
被關聯類的實體名 N  

 

 

 

 

例如,A和B之間是一對一的關系,那么反過來B和A之間的關系也是一對一的。需要在這兩個實體的映射文件中都進行

相應的配置。這樣,才能完整地表示這兩個對象之間的關系。

例如,對於Employee和Person進行主鍵一對一關聯。首先需要在Employee對象的配置文件中定義到Person對象的關聯:

<one-to-one name="person" class="Person">

然后還需要在Person對象的配置文件中定義到Employee對象的關聯:

<one-to-one name="employee" class="Employee" constrained="true">

另外,為了確保兩個對象的主鍵值是相等的,在定義主鍵的時候可以使用名稱為 foreign 的Hibernate 標識符生成策略來實現這一目的。

Person對象主鍵字段的映射信息的配置方法如下所示:

<id name="id' column="ID">
            <generator class="foreign">
                        <param name="property">employee</param>
            </generator>
</id>

 

2、一對多(雙向)關聯關系的映射:

 

<one-to-many
                class="ClassName"
                not-found="ignore|exception"
                entity-name="EntityName"
                node="element-name"
                embed-xml="true|false"
/>        
序號 屬性 含義和作用 必須 默認值
1 class 關聯的目標類 Y  
2 not-found 指名若關聯的對象不存在,該如何處理 N Exception
3 entity-name 被關聯的類的實體名,作為class的替代 N  

 

 

 

 

<set name="telephones" cascade="all" table="Telephones">
        <key column="User_Id"/>
        <one-to-many class="Telephones"/>
</set>       

在通常情況下,要將一對多的關聯關系配置為雙向,這樣可以方便地從任意一方進行數據的維護工作,同時也可以解決上面所提到的問題。

2、多對一(雙向)關聯關系的映射:

通常情況下,關聯關系的主控方設置為“多”的這一方,這樣就可避免需要在“多”的一方的關聯字段中先插入空值的情況出現。

  多對一的關聯關系需要在“多”的這一方使用<many-to-one>來進行配置,配置的方法如下:

<many-to-one name="user" class="User" column="User_Id" />

另外,為了使“多”的這一方變為主控方,還需要在配置“一”的一方增加“inverse=true”的配置(set的屬性)。

在對象之間的關聯關系中,“inverse='false'” 的一方變為主控方,由它來負責維護對象之間的關聯關系。

3、多對多關聯關系的映射:

<many-to-many
                column="column_Name"
                class="ClassName"               
                fetch="join|select"                
                lazy="true|proxy|false"
                not-found="ignore|exception"
                entity-name="EntityName"
                formula="any sql expression"
/> 
序號 屬性 含義和作用 必須 默認值
1
column
中間關聯表中映射到關聯目標表的關聯字段 Y  
2
class
關聯的目標類 Y  
3
fetch

設置抓取數據的策略。這個屬性的可選值有:

  join--外連接抓取

  select--序列選擇抓取

N select
4
lazy

指定對於此關聯對象是否使用延遲加載的策略。這個屬性的可選值有:

  proxy--通過代理進行關聯

  true--此關聯對象采用延遲加載,在該實例變量第一次被訪問時抓取(需要運行時

字節翃的增強)

  false--此關聯對象不采用延遲加載。注意,如果constrained="false",則不能

使用代理,hibernate會采取預先抓取

N  
5
not-found

指名若關聯的對象不存在,該如何處理。這個屬性的可能取值有:

  exception--產生一個異常

  ignore--對於不存在的應用將關聯到Null

N exception
6
entity-name
被關聯類的實體名 N  
7
formula

絕大多數的關聯的關聯都指向其實體的主鍵。在一些少見的情況中,可能會指向其它的一個或多個字段,或者是一個

表達式,這些情況下,可以用一個sql公式來表示

N  

在開發中經常遇到的用戶(User)和角色(Role)的關系就是多對多的關系。一個用戶可以擁有多個角色,同時一個角色又可以被很多的

用戶所擁有。那么在描述這兩個對象之間的關系時就需要建立一個中間表User_Role來確立它們之間的關系。

首先,需要在其中一個對象(例如,User)中配置一個多對多的關聯,如下所示:

<set
        name="roles"
        table="User_Role"
        inverse="true"
        cascade="save-update"
        <key column="Id" />
        <many-to-many column="Role_Id" class="Role">
/set>

同樣,在另一個對象(例如,Role)中需要進行如下配置:

<set
        name="users"
        table="User_Role"
        cascade="save-update"
        <key column="Id" />
        <many-to-many column="User_Id" class="User">
/set>

在這里還是要再次提醒大家,對象之間的關聯關系是雙方向的,在配置的時候通常需要進行雙向配置

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM