由於關系數據模型不允許一個表的外鍵同時參照兩個表的主鍵
因此無法對TABLE_D表的A_ID字段定義外鍵參照約束
而應該通過其他方式
如觸發器
來保證A_ID字段的參照完整性
由於TABLE_D表的A_ID字段既可能參照TABLE_B表的ID主鍵
也可能參照TABLE_C表的ID主鍵
要求TABLE_B表和TALBE_C表的ID主鍵具有相同的SQL類型
在ClassD
hbm
xml文件中
用元素來映射ClassD的a屬性
<any name=
a
meta
type=
string
id
type=
long
cascade=
save
update
>
<meta
value value=
B
class=
ClassB
/>
<meta
value value=
C
class=
ClassC
/>
<column name=
A_TYPE
/>
<column name=
A_ID
/>
</any>
元素的meta
type屬性指定TABLE_D中A_TYPE字段的類型
id
type屬性指定TABLE_D中A_ID字段的類型
子元素設定A_TYPE字段的可選值
在本例中
如果A_TYPE字段取值為
B
表示為ClassB的對象
A_ID字段參照TABLE_B表中的ID主鍵
如果A_TYPE字段取值為
C
表示為ClassC的對象
A_ID字段參照TABLE_C表中的ID主鍵
子元素指定TABLE_D表中的A_TYPE字段和A_ID字段
必須先指定A_TYPE字段
再指定A_ID字段
小結 本章介紹了映射繼承關系的三種方式
繼承關系樹的每個具體類對應一個表
在具體類對應的表中
不僅包含和具體類的屬性對應的字段
還包含和具體類的父類的屬性對應的字段
這種映射方式不支持多態關聯和多態查詢
繼承關系樹的根類對應一個表
在根類對應的表中
不僅包含和根類的屬性對應的字段
還包含和所有子類的屬性對應的字段
這種映射方式支持多態關聯和多態查詢
並且能獲得最佳查詢性能
缺點是需要對關系數據模型進行非常規設計
在數據庫表中加入額外的區分各個子類的字段
此外
不能為所有子類的屬性對應的字段定義not null約束
繼承關系樹的每個類對應一個表
在每個類對應的表中只需包含和這個類本身的屬性對應的字段
子類對應的表參照父類對應的表
這種映射方式支持多態關聯和多態查詢
而且符合關系數據模型的常規設計規則
缺點是它的查詢性能不如第二種映射方式
在這種映射方式下
必須通過表的內連接或左外連接來實現多態查詢和多態關聯
在默認情況下
對於簡單的繼承關系樹可以采用根類對應一個表的映射方式
如果必須保證關系數據模型的數據完整性
可以采用每個類對應一個表的映射方式
對於復雜的繼承關系樹
可以將它分解為幾棵子樹
對每棵子樹采用不同的映射方式
當然
在設計域模型時
應該盡量避免設計過分復雜的繼承關系
這不僅會增加把域模型映射到關系數據模型的難度
而且也會增加在Java程序代碼中操縱持久化對象的復雜度
對於不同的映射方式
必須創建不同的關系數據模型和映射文件
但是域模型是一樣的
域模型中的持久化類的實現也都一樣
只要具備Java編程基礎知識
就能創建具有繼承關系的持久化類
因此本章沒有詳細介紹這些持久化類的創建過程
在此僅提醒一點
子類的完整構造方法不僅負責初始化子類本身的屬性
還應該負責初始化從父類中繼承的屬性
例如以下是HourlyEmployee類的構造方法
public class HourlyEmployee extends Employee{
private double rate;
/** 完整構造方法*/
public HourlyEmployee(String name
double rate
Company company) {
super(name
company);
this
rate=rate;
}
/** 默認構造方法*/
public HourlyEmployee() {}
……
}
Hibernate只會訪問持久化類的默認構造方法
永遠不會訪問其他形式的構造方法
提供以上形式的完整構造方法
主要是為Java應用的編程提供方便
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28491.html