Hibernate之1-N關聯映射,hibernate1-n映射

來源:互聯網
上載者:User

Hibernate之1-N關聯映射,hibernate1-n映射
一、Hibernate之1-N關聯映射

1. 哪邊是 1 , 哪邊是多 ?

     需要從業務的角度來說明。例如,Employee 和 Department 之間就是 n-1 的關聯關係,Order 和 Customer 之間也是 n-1 的關聯關係。

     1). 關聯關係是有方向的:
     2). 如何在類中來建立關聯關係呢 ?              解:通過成員變數的方式即可.

2. 單向 n-1 關聯關係

     1). 域對象中,在 Order 中聲明一個 Customer 類型的成員變數,並提供 setter、getter

     public class Order {

          private Integer orderId;
          private String orderName;
     
          private Customer customer;

          //...
     }

2). 資料表:



3). 如何進行映射:通過 many-to-one 來映射

     ①. 注意:需要映射在 ORDERS 資料表中的外鍵列!

     <many-to-one name="customer" 
          column="CUSTOMER_ID" 
          class="Customer"></many-to-one>

4). API 操作時
     ①. save 時,若先儲存 Order, 在儲存 Customer,則會多出 UPDATE 語句;若先儲存 Customer,再儲存 Order,則只有 INSERT. 建議先儲存 1 的一端的對象

     ②. get 時,
          ◆預設情況下,關聯對象採取 懶載入 策略。即在擷取 Order 時,若不使用關聯的 Customer 的屬性,則不載入 Customer 對象
          ◆有懶載入就可能會發生懶載入異常:org.hibernate.LazyInitializationException。◇什麼時候出現懶載入異常?擷取一個對象,沒有初始化其關聯的屬性,若在 Session 已經關閉的情況下,訪問關聯的屬性,就會拋出懶載入異常。

     ③. update 時,
          ◆若對象本身是一個持久化對象,則在 flush Session 時,會串聯更新其關聯的對象的屬性。
          ◆若對象是游離對象,則不會更新關聯對象的屬性。但可以通過設定 cascade 屬性來使其能夠進行更新

     ④. delete 時,
          ◆刪除對象,只需要 ID 屬性
          ◆防止發生外鍵約束異常

3. 單向 1-n 關聯關係

     1). 域對象:增加集合屬性

     public class Customer {

          private Integer customerId;
          private String customerName;

          //訪問 n 的一端的集合屬性
          private Set<Order> orders = new HashSet<>();
     
          //....
     }

     注意:
     ①. 當 Session 從資料庫中載入 Java 集合時, 建立的是 Hibernate 內建集合類的執行個體,
          因此在持久化類中定義集合屬性時必須把屬性聲明為 Java 介面類型
     ②. 在定義集合屬性時, 通常把它初始化為集合實作類別的一個執行個體. 
          避免應用程式訪問取值為 null 的集合的方法拋出 NullPointerException


     2).關係資料模型

     
     3). 如何進行映射,在Customer.hbm.xml中通過 set 元素

     <set name="orders" table="ORDERS" 
          order-by="ORDER_NAME ASC">
          <key column="CUSTOMER_ID"></key>
          <one-to-many class="Order"/>

     </set>

     4). API 具體操作:

          ①. save 時:因為由 1 的一端來維護關聯關係,所以一定會多出 UPDATE 語句!最好不是有 1 的一端來維護關聯關係
          ②. update 時:
               ◆若把集合對象 clear,預設情況下是把多的一端的外鍵置空
          ③. delete 時:可以刪除 1 的一端,但是把多的一端的外鍵置空

     5). set 的 order-by 屬性:可以指定在查詢集合時,按集合元素對應的資料表的列進行排序!

     <set name="orders" table="ORDERS" 
          order-by="ORDER_NAME ASC">
          <key column="CUSTOMER_ID"></key>
          <one-to-many class="Order"/>
     </set>





----------------------------------------------------雙向關聯映射-----------------------------------------------------
4. 雙向 1-n 關聯關係

     1). 如何進行映射(下面是Customer表,注意兩者之間的對應關係)



     2). set 元素的 inverse 屬性可以指定由哪一方來維護關聯關係,一般地,在雙向 1-n 關聯關係中,1  的一端的 set 的 inverse 都設定為 true,表示有 n 的一端來維護關聯關係!
    ◆ 比如說在Customer表中:
     <set name="orders" table="ORDERS" 
          order-by="ORDER_NAME ASC" inverse="true">
          <key column="CUSTOMER_ID"></key>
          <one-to-many class="Order"/>
      </set>

hibernate 中 既然1-n的雙向映射 1端不控制關聯關係, 那要這個雙向映射有什用,豈不是與n-1是一樣的?

User {
Set<Order> orders;
}

Order {
User user;
}

一般來說我們讓Order來控制關係。即user的配置<set name="orders" inverse="true">
inverse="true"的意思是,請對方控制關係。也即(User不控制關係,Order控制關係)

即我們修改order.setUser(user),則資料庫會更新。
我們修改user.getOrders().add(order),則資料庫不會更新。

至於怎麼體現雙向,那就是我們從資料庫取user的時候,我們可以直接user.getOrders()
裡面將有我們已經添加的order。
 
hibernate有幾種映射關係

Hibernate的關聯關係映射大概有這麼幾種:

1、單向N-1

2、單向1-1

3、單向1-N

4、單向N-N

5、雙向1-N

6、雙向N-N

7、雙向1-1

下面就對這七種關聯關係映射進行一個簡單的總結:

一、單向的多對一

看兩個POJO

public class Person{

private int pid;

private String name;

private Address address;

...//產生相應的getter、setter方法

}

----------------------------------------

public class Address{

private int id;

private String detail;

...//產生相應的getter、setter方法

}

這裡我們需要維護的關係是多個Person可以對應同一個地址,使用單向的N-1映射我們只需要在多的一端加入一個外鍵指向一的一端即可

**看設定檔

<class name="Person">

<id name="id">

<generator class="native"/>

</id>

...//部分欄位配置省略

<many-to-one name="address" column="addressId"/>//關鍵配置

</class>

這樣配置以後hibernate就會幫我們在多的一端(Person)添加一個外鍵addressId指向一的一端

二、單向的1-1(外部索引鍵關聯)

可以採用<many-to-one>標籤,指定多的一端的unique=true,這樣就限制了多的一端的多重性唯一

通過這種手段映射一對一唯一外部索引鍵關聯

設定檔只需要修改為:

<many-to-one name="address" column="addressId" unique="true"/>

三、單向的1-N

**看代碼,我們知道一個班級有多名學生,這就是一個典型的1-N關係

public class Classes {
private int id;
private String name;
private Set students;

...//產生相應的getter、setter方法

}

---------------------------------------------------------------------------

public class Student {
private int id;
private String name;

..//產生相應是getter、setter方法

}

**映射原理:一對多關聯映射,在多的一端添加一個外鍵指向一的一端,它維護的關係是一指向多

**設定檔:

<class name="Classes" table="t_classes">
<id......餘下全文>>
 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.