Hibernate關聯關係配置(一對多、一對一和多對多)

第一種關聯關係:一對多(多對一)數據庫

"一對多"是最廣泛的映射關係,簡單來說就如消費者與訂單的關係。app

一對多:從消費者角的度來講一個消費者能夠有多個訂單,即爲一對多。ui

多對一:從訂單的角度來講多個訂單能夠對應一個消費者,即爲多對一。spa

 

一對多關係在hbm文件中的配置信息:.net

消費者(一方):hibernate

複製代碼

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="com.suxiaolei.hibernate.pojos.Customer" table="customer">
            <!-- 主鍵設置 -->
            <id name="id" type="string">
                <column name="id"></column>
                <generator class="uuid"></generator>
            </id>
            <!-- 屬性設置 -->
            <property name="username" column="username" type="string"></property>
            <property name="balance" column="balance" type="integer"></property>
            
            <set name="orders" inverse="true" cascade="all">
                <key column="customer_id" ></key>
                <one-to-many class="com.suxiaolei.hibernate.pojos.Order"/>
            </set>
        </class>
    </hibernate-mapping>

複製代碼

訂單(多方):設計

複製代碼

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="com.suxiaolei.hibernate.pojos.Order" table="orders">
            <id name="id" type="string">
                <column name="id"></column>
                <generator class="uuid"></generator>
            </id>
            
            <property name="orderNumber" column="orderNumber" type="string"></property>
            <property name="cost" column="cost" type="integer"></property>
            
            <many-to-one name="customer" class="com.suxiaolei.hibernate.pojos.Customer" 
                         column="customer_id" cascade="save-update">
            </many-to-one>        
        </class>
    </hibernate-mapping>

複製代碼

  "一對多"關聯關係,Customer方對應多個Order方,因此Customer包含一個集合用於存儲多個Order,Order包含一個Customer用於儲存關聯本身的Customer。3d

一對多關聯關係有一種特例:自身一對多關聯。例如:xml

 

自身一對多關聯自身的hbm文件設置:對象

複製代碼

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping>
        <class name="com.suxiaolei.hibernate.pojos.Category" table="category">
            <id name="id" type="string">
                <column name="id"></column>
                <generator class="uuid"></generator>
            </id>
            
            <property name="name" column="name" type="string"></property>
            
            <set name="chidrenCategories" cascade="all" inverse="true">
                <key column="category_id"></key>
                <one-to-many class="com.suxiaolei.hibernate.pojos.Category"/>
            </set>
            
            <many-to-one name="parentCategory" class="com.suxiaolei.hibernate.pojos.Category" column="category_id">
            </many-to-one>
            
        </class>
    </hibernate-mapping>

複製代碼

外鍵存放父親的主鍵。

第二種關聯關係:多對多

  多對多關係也很常見,例如學生與選修課之間的關係,一個學生能夠選擇多門選修課,而每一個選修課又能夠被多名學生選擇。數據庫中的多對多關聯關係通常需採用中間表的方式處理,將多對多轉化爲兩個一對多。

數據表間多對多關係以下圖:

多對多關係在hbm文件中的配置信息:

學生:

複製代碼

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.suxiaolei.hibernate.pojos.Student" table="student">
        <id name="id" type="integer">
            <column name="id"></column>
            <generator class="increment"></generator>
        </id>

        <property name="name" column="name" type="string"></property>

        <set name="courses" inverse="false" cascade="save-update" table="student_course">
            <key column="student_id"></key>
            <many-to-many class="com.suxiaolei.hibernate.pojos.Course"
                column="course_id"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

複製代碼

課程:

複製代碼

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.suxiaolei.hibernate.pojos.Course" table="course">
        <id name="id" type="integer">
            <column name="id"></column>
            <generator class="increment"></generator>
        </id>

        <property name="name" column="name" type="string"></property>

        <set name="students" inverse="true" cascade="save-update" table="student_course">
            <key column="course_id"></key>
            <many-to-many class="com.suxiaolei.hibernate.pojos.Student"
                column="student_id"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

複製代碼

  其實多對多就是兩個一對多,它的配置沒什麼新奇的相對於一對多。在多對多的關係設計中,通常都會使用一箇中間表將他們拆分紅兩個一對多。<set>標籤中的"table"屬性就是用於指定中間表的。中間表通常包含兩個表的主鍵值,該表用於存儲兩表之間的關係。因爲被拆成了兩個一對多,中間表是多方,它是使用外鍵關聯的,<key>是用於指定外鍵的,用於從中間表取出相應的數據。中間表每一行數據只包含了兩個關係表的主鍵,要獲取與本身關聯的對象集合,還須要取出由外鍵所得到的記錄中的另外一個主鍵值,由它到對應的表中取出數據,填充到集合中。<many-to-many>中的"column"屬性是用於指定按那一列的值獲取對應的數據。

  例如用course表來講,它與student表使用一箇中間表student_course關聯。若是要獲取course記錄對應的學生記錄,首先須要使用外鍵"course_id"從student_course表中取得相應的數據,而後在取得的數據中使用"student_id"列的值,在student表中檢索出相關的student數據。其實,爲了便於理解,你能夠在使用course表的使用就把中間表當作是student表,反之亦然。這樣就可使用一對多的思惟來理解了,多方關聯一方須要外鍵那麼在本例子中就須要"course_id"來關。


第三種關聯關係:一對一
  一對一關係就球隊與球隊所在地之間的關係,一支球隊僅有一個地址,而一個地區也僅有一支球隊(貌似有點勉強,將就下吧)。數據表間一對一關係的表現有兩種,一種是外鍵關聯,一種是主鍵關聯。圖示以下:

一對一外鍵關聯:

一對一主鍵關聯:要求兩個表的主鍵必須徹底一致,經過兩個表的主鍵創建關聯關係:

一對一外鍵關聯在hbm文件中的配置信息:

地址:

複製代碼

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.suxiaolei.hibernate.pojos.Adress" table="adress">
        <id name="id" type="integer">
            <column name="id"></column>
            <generator class="increment"></generator>
        </id>

        <property name="city" column="city" type="string"></property>
        
        <one-to-one name="team" class="com.suxiaolei.hibernate.pojos.Team" cascade="all"></one-to-one>

    </class>
</hibernate-mapping>

複製代碼

球隊:

複製代碼

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.suxiaolei.hibernate.pojos.Team" table="team">
        <id name="id" type="integer">
            <column name="id"></column>
            <generator class="increment"></generator>
        </id>

        <property name="name" column="name" type="string"></property>
        
        <many-to-one name="adress" class="com.suxiaolei.hibernate.pojos.Adress" column="adress_id" unique="true"></many-to-one>

    </class>
</hibernate-mapping>

複製代碼

  一對一外鍵關聯,其實能夠看作是一對多的一種特殊形式,多方退化成一。多方退化成一隻須要在<many-to-one>標籤中設置"unique"="true"。
一對一主鍵關聯在hbm文件中的配置信息:

地址:

複製代碼

<hibernate-mapping>
    <class name="com.suxiaolei.hibernate.pojos.Adress" table="adress">
        <id name="id" type="integer">
            <column name="id"></column>
            <generator class="increment"></generator>
        </id>

        <property name="city" column="city" type="string"></property>
        
        <one-to-one name="team" class="com.suxiaolei.hibernate.pojos.Team" cascade="all"></one-to-one>

    </class>
</hibernate-mapping>

複製代碼

球隊:

複製代碼

<hibernate-mapping>
    <class name="com.suxiaolei.hibernate.pojos.Team" table="team">
        <id name="id" type="integer">
            <column name="id"></column>
            <generator class="foreign">
                <param name="property">adress</param>
            </generator>
        </id>

        <property name="name" column="name" type="string"></property>
        
        <one-to-one name="adress" class="com.suxiaolei.hibernate.pojos.Adress" cascade="all"></one-to-one>

    </class>
</hibernate-mapping>

複製代碼

一對一主鍵關聯,是讓兩張的主鍵值同樣。要使兩表的主鍵相同,只能一張表生成主鍵,另外一張表參考主鍵。

<generator class="foreign">

  <param name="property">adress</param>

</generator>

"class"="foreign"就是設置team表的主鍵參照adress屬性的主鍵值。

相關文章
相關標籤/搜索