Hibernate中有以下三種策略將這種關系映射到數據表上:
· 每個類層次結構一個表(table per class hierarchy)
· 每個子類一個表(table per subclass)
· 每個具體類一個表(table per concrete class)(有一些限制)
 
   每個類層次結構一個表的方式是將所有繼承同一父類別的對象儲存在同一個表格中,為了做到這一點,
需要在表中使用識別字段來表示某一列(row)是屬于某個子類別或父類別,在這個主題中我們將先說明這個方法。


一個例子如下:
·  類Animal.java

Animal.java

package com.jason.inheritance;
/**
 * @hibernate.class
 *   table="Animal"
 *   discriminator-value="Animal"
 * @hibernate.discriminator
 *   column="ANIMAL_TYPE"
 *   type="string"
 *   length = "10"
 */
public class Animal {
 private Long id;
 private String name;
 /**
  * @hibernate.id
  *   column="ID"
  *   generator-class="hilo"
  *   unsaved-value="null"
  */
 public Long getId() {
  return id;
 }
 public void setId(Long id) {
  this.id = id;
 }
 /**
  * @hibernate.property
  *   length = "24"
  */
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public void makeSound(){};
}

·  子類Cat.java
package com.jason.inheritance;
public
class Cat extends Animal { privateString FurColor; publicvoid makeSound() { System.out.println("喵喵"); } publicString getFurColor() { return FurColor; } publicvoid setFurColor(String furColor) { FurColor = furColor; } }

·  子類Dog.java

package com.jason.inheritance;

/**
 * @hibernate.subclass
 *   discriminator-value="Dog"
 */
public class Dog extends Animal {
 private String category;

 public void makeSound() {
  System.out.println("汪汪");
 }

 /**
  * @hibernate.property
  *   length = "24"
  */
 public String getCategory() {
  return category;
 }

 public void setCategory(String category) {
  this.category = category;
 }
}

 



·  Animal.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "
<hibernate-mapping>
 <class name="com.jason.inheritance.Animal" table="Animal"
  dynamic-update="false" dynamic-insert="true" select-before-update="false"
  optimistic-lock="version" discriminator-value="Animal">
  
  <id name="id" column="ID" type="java.lang.Long" unsaved-value="null">
   <generator class="hilo">
   </generator>
  </id>
  
  <discriminator column="ANIMAL_TYPE" type="string" length="10"/>
  
  <property name="name" type="java.lang.String" update="true" insert="true"
   access="property" column="name" length="24"/>
  
  <subclass name="com.jason.inheritance.Cat" dynamic-update="false"
   dynamic-insert="false" discriminator-value="Cat">
   
   <property name="furColor" type="java.lang.String" update="true"
    insert="true" access="property" column="furColor" length="24"/>
  </subclass>
  <subclass name="com.jason.inheritance.Dog" dynamic-update="false"
   dynamic-insert="false" discriminator-value="Dog">
   
   <property name="category" type="java.lang.String" update="true"
    insert="true" access="property" column="category" length="24"/>
  </subclass>
  
 </class>
 
</hibernate-mapping>


      顯然對應的表是Animal(ID, ANIMAL_TYPE, name, furColor, category)
      需要在表中使用識別字段來表示某一列(row)是屬于某個子類別或父類別,
就是用ANIMAL_TYPE來表示的!
      插入記錄的sql如下:
Hibernate: insert into Animal (name, ANIMAL_TYPE, ID) values (?, 'Animal', ?)
Hibernate: insert into Animal (name, furColor, ANIMAL_TYPE, ID) values (?, ?, 'Cat', ?)
Hibernate: insert into Animal (name, category, ANIMAL_TYPE, ID) values (?, ?, 'Dog', ?)


● 優點:
· 實現簡單。
· 支持多態——對象角色發生變化,或存在多重角色時。
· 報表操作實現簡單:表中包含了所有信息。

● 缺點:
· 增加類層次中的耦合。類層次中任何類的屬性的增加都會導致表的變更;某個子類屬性的修改會影響到整個層次結構,而不僅僅是該子類。
· 浪費了一些數據庫空間。浪費空間的多少取決于繼承層次的深度。層次越深,不同的屬性越多,屬性的全集就越大,也就越浪費空間。
· 要求由子類定義的字段不能有非空(NOT NULL)約束












參考:

· HIBERNATE - 符合Java習慣的關系數據庫持久化(第8章)