Hibernate關(guān)系映射2:雙向1-N關(guān)聯(lián)

2018-09-28 14:19 更新

我最近在復(fù)習(xí)一下關(guān)于Hibernate關(guān)系映射的知識(shí),看了書本的介紹以及視頻。這幾篇博客都是對(duì)學(xué)到知識(shí)的一點(diǎn)總結(jié)。當(dāng)然,這些這是最基本的能夠?qū)崿F(xiàn)關(guān)聯(lián)關(guān)系的配置,在實(shí)際的使用中,還有很多參數(shù)需要根據(jù)情況來設(shè)置。但也算是對(duì)以后開發(fā)過程中遇到遺忘的地方可以進(jìn)行查閱。

在本文中使用的Demo也都已經(jīng)上傳到github中,里邊有詳細(xì)的運(yùn)行說明。Github地址:HibernateRelationMapping

雙向1-N關(guān)聯(lián)


對(duì)于1-N關(guān)聯(lián),Hibernate推薦使用雙向關(guān)聯(lián),而且不要讓1的一端控制關(guān)聯(lián)關(guān)系,而使用N的一端控制關(guān)聯(lián)關(guān)系。

雙向的N-1關(guān)聯(lián)與1-N關(guān)聯(lián)是完全相同的兩種情形。兩端都需要增加對(duì)關(guān)聯(lián)屬性的訪問,N的一端增加引用到關(guān)聯(lián)實(shí)體的屬性,1的一端增加集合屬性,集合元素為關(guān)聯(lián)實(shí)體。

域模型

從 Order 到 Customer 的多對(duì)一雙向關(guān)聯(lián)需要在Order 類中定義一個(gè) Customer 屬性, 而在 Customer 類中需定義存放 Order 對(duì)象的集合屬性

圖1

關(guān)系數(shù)據(jù)模型

ORDERS 表中的 CUSTOMER_ID 參照 CUSTOMER 表的主鍵

圖2

Notice

當(dāng)Session從數(shù)據(jù)庫中加載Java集合時(shí),創(chuàng)建的是Hibernate內(nèi)置集合類的實(shí)例,因此,在持久化類中定義集合屬性時(shí),必須把屬性聲明為Java接口

  • Hibernate的內(nèi)置集合類具有集合代理功能,支持延遲檢索策略
  • 事實(shí)上,Hibernate的內(nèi)置集合類封裝了JDK中的集合類,這使得Hibernate能夠?qū)彺嬷械募蠈?duì)象進(jìn)行臟檢查,按照集合對(duì)象的狀態(tài)來同步更新數(shù)據(jù)庫。

在定義集合屬性時(shí),通常把它初始化為集合實(shí)現(xiàn)類的一個(gè)實(shí)例,這樣可以提高程序的健壯性,避免應(yīng)用程序訪問取值為null的集合的方法。

例如:private Set<Order> orders = new HashSet<Order>();

Demo


實(shí)體對(duì)象

public class Customer {
    private Integer customerId;
    private String customerName;
    private Set<Order> orders = new HashSet<Order>();
    //省去get和set
}
public class Order {
    private Integer orderId;
    private String orderName;
    private Customer customer;
//省去get和set
}

Customer.hbm.xml

<hibernate-mapping package="com.lihui.hibernate.double_n_1">
    <class name="Customer" table="CUSTOMERS">
        <id name="customerId" type="java.lang.Integer">
            <column name="CUSTOMER_ID" />
            <generator class="native" />
        </id>
        <property name="customerName" type="java.lang.String">
            <column name="CUSTOMER_NAME" />
        </property>
        <set name="orders"  inverse="true">
            <key column="CUSTOMER_ID"></key>
            <one-to-many class="Order"/>
        </set>
    </class>
</hibernate-mapping>

set

name屬性: 設(shè)定待映射的持久化類的屬性的

inverse 屬性:

  • 在hibernate中通過對(duì) inverse 屬性的來決定是由雙向關(guān)聯(lián)的哪一方來維護(hù)表和表之間的關(guān)系。 inverse = false 的為主動(dòng)方,inverse = true 的為被動(dòng)方, 由主動(dòng)方負(fù)責(zé)維護(hù)關(guān)聯(lián)關(guān)系。在沒有設(shè)置 inverse=true 的情況下,父子兩邊都維護(hù)父子關(guān)系
  • 在 1-N 關(guān)系中,將 N 方設(shè)為主控方將有助于性能改善(如果要國家元首記住全國人民的名字,不是太可能,但要讓全國人民知道國家元首,就容易的多)
  • 在 1-N 關(guān)系中,若將 1 方設(shè)為主控方,會(huì)額外多出 update 語句。插入數(shù)據(jù)時(shí)無法同時(shí)插入外鍵列,因而無法為外鍵列添加非空約束.

order-by 屬性:

  • 如果設(shè)置了該屬性, 當(dāng) Hibernate 通過 select 語句到數(shù)據(jù)庫中檢索集合對(duì)象時(shí), 利用 order by 子句進(jìn)行排序
  • order-by 屬性中還可以加入 SQL 函數(shù)例如:圖3

key

設(shè)定與所關(guān)聯(lián)的持久化類對(duì)應(yīng)的表的外鍵

  • column: 指定關(guān)聯(lián)表的外鍵名

one-to-many

設(shè)定集合屬性中所關(guān)聯(lián)的持久化類

  • class: 指定關(guān)聯(lián)的持久化類的類名

Order.hbm.xml

<hibernate-mapping package="com.lihui.hibernate.double_n_1">
    <class name="Order" table="ORDERS">
        <id name="orderId" type="java.lang.Integer">
            <column name="ORDER_ID" />
            <generator class="native" />
        </id>
        <property name="orderName" type="java.lang.String">
            <column name="ORDER_NAME" />
        </property>
        <many-to-one name="customer" class="Customer" cascade="all" column="CUSTOMER_ID"></many-to-one>
    </class>
</hibernate-mapping>  
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)