映射

【需求】html

      有三個類Animal類、Pig類、Bird類,繼承關係以下圖所示node

 

具體的繼承實現的有三種策略:web

1)單表繼承數據庫

     每一個類繼承樹使用一個表app

2)具體表繼承this

     每一個子類一個表url

3)類表繼承spa

     每一個具體類一個表.net

【單表繼承】hibernate

1、具體的實體類如上圖所示再也不贅述,咱們主要來看看映射文件:

 

[html]  view plain  copy
  1. <span style="font-family:Comic Sans MS;"><?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC   
  3.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  5. <hibernate-mapping package="com.bjpowernode.hibernate">  
  6.     <class name="Animal" table="t_animal" lazy="false">  
  7.         <id name="id">  
  8.             <generator class="native"/>  
  9.         </id>  
  10.         <discriminator column="type" type="string"/>  
  11.         <property name="name"/>  
  12.         <property name="sex"/>  
  13.         <subclass name="Pig" discriminator-value="P">  
  14.             <property name="weight"/>  
  15.         </subclass>  
  16.         <subclass name="Bird" discriminator-value="B">  
  17.             <property name="height"/>  
  18.         </subclass>  
  19.     </class>  
  20. </hibernate-mapping></span>  

 

2、分析說明

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

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

    1)父類用普通的<class>標籤訂義

    2)在父類中定義一個discriminator,即指定這個區分的字段的名稱和類型

      如:<discriminatorcolumn=」XXX」 type=」string」/>

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

       ①Subclass標籤的name屬性是子類的全路徑名

       ②在Subclass標籤中,用discriminator-value屬性來標明本子類的discriminator字段(用來區分不一樣類的字段)的值

       ③Subclass標籤,既能夠被class標籤所包含(這種包含關係正是代表了類之間的繼承關係),也能夠與class標籤平行。

       ④當subclass標籤的定義與class標籤平行的時候,須要在subclass標籤中,添加extends屬性,裏面的值是父類的全路徑名稱。

       ⑤子類的其它屬性,像普通類同樣,定義在subclass標籤的內部。

3、優缺點

       ①表中引入了區分子類的字段,只須要維護一張表,比較方便。

       ②由於只有一張表,表中冗餘字段會隨子類增多,而且靈活性差。

【具體表繼承】

1、映射文件

 

[html]  view plain  copy
  1. <span style="font-family:Comic Sans MS;"><?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC   
  3.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  5. <hibernate-mapping package="com.bjpowernode.hibernate">  
  6.     <class name="Animal" table="t_animal">  
  7.         <id name="id">  
  8.             <generator class="native"/>  
  9.         </id>  
  10.         <property name="name"/>  
  11.         <property name="sex"/>  
  12.         <joined-subclass name="Pig" table="t_pig">  
  13.             <key column="pid"/>  
  14.             <property name="weight"/>  
  15.         </joined-subclass>  
  16.         <joined-subclass name="Bird" table="t_bird">  
  17.             <key column="bid"/>  
  18.             <property name="height"/>  
  19.         </joined-subclass>  
  20.     </class>  
  21. </hibernate-mapping></span>  

 

2、分析說明

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

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

      1)父類用普通的<class>標籤訂義便可

      2)父類再也不須要定義discriminator字段

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

       ①Joined-subclass標籤的name屬性是子類的全路徑名

       ②Joined-subclass標籤須要包含一個key標籤,這個標籤指定了子類和父類之間是經過哪一個字段來關聯的。

如:<keycolumn=」PARENT_KEY_ID」/>,這裏的column,實際上就是父類的主鍵對應的映射字段名稱。

       ③Joined-subclass標籤,既能夠被class標籤所包含(這種包含關係正是代表了類之間的繼承關係),也能夠與class標籤平行。

       ④當Joined-subclass標籤的定義與class標籤平行的時候,須要在Joined-subclass標籤中,添加extends屬性,裏面的值是父類的全路徑名稱。

       ⑤子類的其它屬性,像普通類同樣,定義在joined-subclass標籤的內部。

3、優缺點

       ①符合關係模型的設計原則,且不存在冗餘。

       ②每一個類都有對應的表,方便維護。

       ③對於子類的持久化至少須要處理兩個表。

【類表繼承】

1、映射文件

 

[html]  view plain  copy
  1. <span style="font-family:Comic Sans MS;"><?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC   
  3.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  5. <hibernate-mapping package="com.bjpowernode.hibernate">  
  6.     <class name="Animal" table="t_animal" abstract="true">  
  7.         <id name="id">  
  8.             <generator class="assigned"/>  
  9.         </id>  
  10.         <property name="name"/>  
  11.         <property name="sex"/>  
  12.         <union-subclass name="Pig" table="t_pig">  
  13.             <property name="weight"/>  
  14.         </union-subclass>  
  15.         <union-subclass name="Bird" table="t_bird">  
  16.             <property name="height"/>  
  17.         </union-subclass>  
  18.     </class>  
  19. </hibernate-mapping></span>  

 

2、分析說明

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

joined-subclass定義的子類的表,只包含子類特有屬性映射的字段)。實現這種策略的時候,有以下步驟:

     1)父類用普通<class>標籤訂義便可

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

       ①Union-subclass標籤再也不須要包含key標籤(與joined-subclass不一樣)

       ②Union-subclass標籤,既能夠被class標籤所包含(這種包含關係正是代表了類之間的繼承關係),也能夠與class標籤平行。

       ③當Union-subclass標籤的定義與class標籤平行的時候,須要在Union-subclass標籤中,添加extends屬性,裏面的值是父類的全路徑名稱。

       ④子類的其它屬性,像普通類同樣,定義在Union-subclass標籤的內部。這個時候,雖然在union-subclass裏面定義的只有子類的屬性,可是由於它繼承了父類,因此,不須要定義其它的屬性,在映射到數據庫表的時候,依然包含了父類的全部屬性的映射字段。

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

3、優缺點

       ①符合關係模型的設計原則,但有表中存在重複字段的問題。

       ②若要修改基類,則須要對基類以及該類的子類所對應的全部表都進行修改。

       ③映射的靈活性很大,子類能夠包括基類屬性在內的每個屬性進行單獨配置

相關文章
相關標籤/搜索