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

Hibernate 繼承映射完全指南(三):每具體類一表策略實戰與缺陷分析

     編輯:Java 相關知識

每具體類一表 是最直觀但功能最受限的策略:每個具體子類獨立映射一張表,包含所有繼承字段,父類若為抽象則不建表。本文通過完整代碼演示其操作細節,揭示「無多態查詢/關聯」的核心缺陷。

表結構:獨立表含繼承字段

  • HOURLY_EMPLOYEES (HE) — ID, NAME, RATE, COMPANY_ID
  • SALARIED_EMPLOYEES (SE) — ID, NAME, SALARY, COMPANY_ID
  • COMPANIES — 公司表

無父類 EMPLOYEES 表。ID 由各表自增或共享序列生成。

映射文件:獨立 .hbm.xml

<!-- HourlyEmployee.hbm.xml -->
<hibernate-mapping>
  <class name="mypack.HourlyEmployee" table="HOURLY_EMPLOYEES">
    <id name="id" column="ID"><generator class="increment"/></id>
    <property name="name" column="NAME"/>
    <property name="rate" column="RATE" type="double"/>
    <many-to-one name="company" column="COMPANY_ID" class="mypack.Company"/>
  </class>
</hibernate-mapping>

<!-- SalariedEmployee.hbm.xml 類似 -->

初始化需註冊所有具體類:

config.addClass(Company.class)
      .addClass(HourlyEmployee.class)
      .addClass(SalariedEmployee.class);

運行實戰:手動組裝多態

1. 查詢所有 Employee (無原生支援)

public List findAllEmployees() {
    List results = new ArrayList();
    // 必須分別查詢再合併
    results.addAll(session.find("from HourlyEmployee"));
    results.addAll(session.find("from SalariedEmployee"));
    return results;
}

生成兩條獨立 SQL:SELECT * FROM HOURLY_EMPLOYEES; / SELECT * FROM SALARIED_EMPLOYEES;

❌ 無法用 from Employee 進行多態查詢(Employee 為抽象類會拋異常,具體類只查自身表)。

2. 多態關聯:Company → Employees (不支援)

Company.employees 集合無法自動包含子類實例。業務代碼必須手動查詢並填充:

Company c = (Company) session.load(Company.class, id);
List hourly = session.find("from HourlyEmployee h where h.company.id=?", id);
List salaried = session.find("from SalariedEmployee s where s.company.id=?", id);
c.getEmployees().addAll(hourly);
c.getEmployees().addAll(salaried);

❌ 破壞透明持久化,增加業務代碼複雜度。

3. 保存操作:單表 INSERT

session.save(new HourlyEmployee("Mary", 300, company));

SQL:INSERT INTO HOURLY_EMPLOYEES (ID, NAME, RATE, COMPANY_ID) VALUES (3, 'Mary', 300, 1);

✅ 單表操作簡單高效,但主鍵生成策略需跨表協調(如共享序列)。

核心缺陷總結

特性支援度影響
多態查詢 (from Parent)❌ 不支援需手動 UNION/合併集合
多態關聯 (One-to-Many)❌ 不支援需手動查詢填充集合
主鍵跨表唯一⚠️ 需額外機制推薦共享序列或 UUID
Schema 修改⚠️ 需修改所有子表維護成本高

適用場景(極少)

  • 完全無多態需求,子類獨立演化
  • 歷史系統重構,暫時兼容
  • 極簡場景,開發團隊不熟悉 Hibernate 進階映射

結論:除非極特殊理由,強烈不建議 在新項目使用此策略。其「看似簡單」實則將複雜度轉移給了業務代碼,違背 ORM 透明持久化初衷。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved