首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 3 學習筆記(十五):繼承映射三大策略深度比較

     編輯:Java 相關知識

繼承映射三種策略概覽

策略資料表數優點缺點適用場景
Table per Concrete Class每個具體類一張表無 JOIN,查詢快;結構簡單無法共享主鍵;多型查詢需 UNION;修改父類欄位需改所有表繼承層次淺、欄位差異大、極少多型查詢
Table per Class Hierarchy單表查詢最快(無 JOIN);結構簡單子類欄位必須 nullable;表欄位多、稀疏;歧視欄位佔空間繼承層次淺、子類欄位少、頻繁多型查詢
Table per Subclass父類一表 + 每子類一表正規化程度高;無 nullable 問題;支援外鍵約束查詢需 JOIN;多型查詢效能較差繼承層次深、子類欄位多、重視資料完整性

策略一:Table per Concrete Class(具體類別各自一表)

資料表

Concrete Class 表結構

CREATE TABLE defaultuser (id PK, name, someProperty);
CREATE TABLE poweruser (id PK, name, otherProperty);

映射:各自獨立 <class>,無共同父類映射

<class name="DefaultUser" table="defaultuser"> ... </class>
<class name="PowerUser" table="poweruser"> ... </class>

多型查詢

from com.hb3.pack_08.model.User  -- Hibernate 產生 UNION ALL 查詢
注意:若查詢 from java.lang.Object 會掃描資料庫所有表,極其危險,嚴禁生產使用。

策略二:Table per Class Hierarchy(單表策略)

資料表

單表結構

CREATE TABLE user (
    id PK, userType VARCHAR(50) NOT NULL,  -- 歧視欄位
    name, someProperty, otherProperty
);

映射:父類定義 <discriminator>,子類用 <subclass>

<class name="User" table="user">
    <id name="id" .../>
    <discriminator column="userType" type="string"/>
    <property name="name"/>
    <subclass name="DefaultUser" discriminator-value="Default">
        <property name="someProperty"/>
    </subclass>
    <subclass name="PowerUser" discriminator-value="Power">
        <property name="otherProperty"/>
    </subclass>
</class>

所有子類欄位在同一表,**必須允許 NULL**。

策略三:Table per Subclass(子類別獨立表)

資料表

Subclass 表結構

CREATE TABLE user (id PK, name);
CREATE TABLE defaultuser (id PK FK, someProperty);
CREATE TABLE poweruser (id PK FK, otherProperty);

映射:父類 <class>,子類用 <joined-subclass>

<class name="User" table="user">
    <id name="id" .../>
    <property name="name"/>
    <joined-subclass name="DefaultUser" table="defaultuser">
        <key column="id"/>
        <property name="someProperty"/>
    </joined-subclass>
    <joined-subclass name="PowerUser" table="poweruser">
        <key column="id"/>
        <property name="otherProperty"/>
    </joined-subclass>
</class>

子類表主鍵同時是指向父表的外鍵,<key column="id"/> 對應父表主鍵。

多型查詢行為比較

三種策略下,from User 皆能查出所有子類實例,但 SQL 差異巨大:

  • Concrete Class:UNION ALL 多表查詢
  • Class Hierarchy:單表 WHERE userType IN (...)
  • Subclass:LEFT OUTER JOIN 多表關聯

選型決策樹

  1. 是否需要多型查詢?否 → Concrete Class 可考慮。
  2. 子類欄位多 / 非 NULL 需求強 → Subclass。
  3. 子類欄位少 / 查詢效能至上 → Class Hierarchy。
  4. 混合場景:可對不同繼承樹採用不同策略(Hibernate 支援混合)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved