Hibernate的繼承映射

對象模型示例:

繼承映射的實現方式有如下三種:

  • (一)每棵類繼承樹一張表
  • (二)每一個類一張表
  • (三)每一個子類一張表

(一)每棵類繼承樹一張表

關係模型以下:git

映射文件以下:github

<hibernate-mapping package="com.nnngu">  
    <class name="Animal" table="t_animal" lazy="false">  
        <id name="id">  
            <generator class="native"/>  
        </id>  
        <discriminator column="type" type="string"/>  
        <property name="name"/>  
        <property name="sex"/>  
        <subclass name="Pig" discriminator-value="P">  
            <property name="weight"/>  
        </subclass>  
        <subclass name="Bird" discriminator-value="B">  
            <property name="height"/>  
        </subclass>  
    </class>  
</hibernate-mapping>

說明:數據庫

由於類繼承樹確定是對應多個類,要把多個類的信息存放在一張表中,必須有某種機制來區分哪些記錄是屬於哪一個類的。這種機制就是,在表中添加一個字段,用這個字段的值來進行區分。app

用hibernate實現這種策略的時候,有以下步驟:post

一、父類用普通的<class>標籤訂義hibernate

二、在父類中定義一個discriminator,即指定這個區分的字段的名稱和類型
如:<discriminator column=」XXX」 type=」string」/>code

三、子類使用<subclass>標籤訂義,在定義subclass的時候,須要注意以下幾點:xml

  • Subclass標籤的name屬性是子類的全路徑名
  • 在Subclass標籤中,用discriminator-value屬性來標明本子類的discriminator字段(用來區分不一樣類的字段)的值
  • Subclass既能夠被class標籤所包含(這種包含關係正是代表了類之間的繼承關係),也能夠與class標籤平行。當subclass標籤的定義與class標籤平行的時候,須要在subclass標籤中,添加extends屬性,裏面的值是父類的全路徑名稱。
  • 子類的其它屬性,像普通類同樣,定義在subclass標籤的內部。
  • 關於鑑別值在存儲的時候hibernate會自動存儲,在加載的時候會根據鑑別值取得相關的對象

(二)每一個類一張表

關係模型以下:對象

映射文件以下:blog

<hibernate-mapping package="com.nnngu">  
    <class name="Animal" table="t_animal">  
        <id name="id">  
            <generator class="native"/>  
        </id>  
        <property name="name"/>  
        <property name="sex"/>  
        <joined-subclass name="Pig" table="t_pig">  
            <key column="pid"/>  
            <property name="weight"/>  
        </joined-subclass>  
        <joined-subclass name="Bird" table="t_bird">  
            <key column="bid"/>  
            <property name="height"/>  
        </joined-subclass>  
    </class>  
</hibernate-mapping>

說明:

這種策略是使用joined-subclass標籤來定義子類的。父類、子類,每一個類都對應一張數據庫表。
在父類對應的數據庫表中,實際上會存儲全部的記錄,包括父類和子類的記錄;在子類對應的數據庫表中,這個表只定義了子類中所特有的屬性映射的字段。子類與父類,經過相同的主鍵值來關聯。

實現這種策略的時候,有以下步驟:

一、父類用普通的<class>標籤訂義便可

二、父類再也不須要定義discriminator字段

三、子類用<joined-subclass>標籤訂義,在定義joined-subclass的時候,須要注意以下幾點:

  • joined-subclass標籤的name屬性是子類的全路徑名
  • joined-subclass標籤須要包含一個key標籤,這個標籤指定了子類和父類之間是經過哪一個字段來關聯的。如:<key column=」PARENT_KEY_ID」/>,這裏的column,實際上就是父類的主鍵對應的映射字段名稱。
  • joined-subclass標籤,既能夠被class標籤所包含(這種包含關係正是代表了類之間的繼承關係),也能夠與class標籤平行。 當joined-subclass標籤的定義與class標籤平行的時候,須要在joined-subclass標籤中,添加extends屬性,裏面的值是父類的全路徑名稱。子類的其它屬性,像普通類同樣,定義在joined-subclass標籤的內部。

(三)每一個子類一張表

關係模型以下:

映射文件以下:

<hibernate-mapping package="com.nnngu">  
    <class name="Animal" table="t_animal" abstract="true">  
        <id name="id">  
            <generator class="assigned"/>  
        </id>  
        <property name="name"/>  
        <property name="sex"/>  
        <union-subclass name="Pig" table="t_pig">  
            <property name="weight"/>  
        </union-subclass>  
        <union-subclass name="Bird" table="t_bird">  
            <property name="height"/>  
        </union-subclass>  
    </class>  
</hibernate-mapping>

說明:

這種策略是使用union-subclass標籤來定義子類的。每一個子類對應一張表,並且這個表的信息是完備的,即包含了全部從父類繼承下來的屬性映射的字段(這就是它跟joined-subclass的不一樣之處,joined-subclass定義的子類的表,只包含子類特有屬性映射的字段)。

實現這種策略的時候,有以下步驟:

一、父類用普通<class>標籤訂義便可

二、子類用<union-subclass>標籤訂義,在定義union-subclass的時候,須要注意以下幾點:

  • union-subclass標籤再也不須要包含key標籤(與joined-subclass不一樣)
  • union-subclass標籤,既能夠被class標籤所包含(這種包含關係正是代表了類之間的繼承關係),也能夠與class標籤平行。 當union-subclass標籤的定義與class標籤平行的時候,須要在union-subclass標籤中,添加extends屬性,裏面的值是父類的全路徑名稱。
  • 子類的其它屬性,像普通類同樣,定義在union-subclass標籤的內部。這個時候,雖然在union-subclass裏面定義的只有子類的屬性,可是由於它繼承了父類,因此,不須要定義其它的屬性,在映射到數據庫表的時候,依然包含了父類的全部屬性的映射字段。

注意:在保存對象的時候id不能重複(不能使用數據庫的自增方式生成主鍵)


本文永久更新地址:https://github.com/nnngu/LearningNotes/blob/master/_posts/2018-03-23-Hibernate%E7%9A%84%E7%BB%A7%E6%89%BF%E6%98%A0%E5%B0%84.md

相關文章
相關標籤/搜索