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

Eclipse 快速上手 Hibernate:繼承映射策略之「每個子類一張表」

     編輯:Java 相關知識

前言

在上一篇《Eclipse 快速上手 Hibernate:繼承映射 (1)》中,我們詳細探討了「每個類層次結構一張表」的策略。本文將繼續深入,介紹另一種常見的繼承映射策略——「每個子類一張表」。為避免重複,專案建立與基礎配置等共通部分請參考前文。

一、專案結構與類設計

沿用現有的 InheritanceMapping Java 專案。在包 javamxj.inheritance.two 下建立以下類別:

1. 父類別:Vehicle.java

父類別僅包含基本屬性 id 和 name,對應資料庫中的主表。

package javamxj.inheritance.two;

/**
 * @hibernate.class
 */
public class Vehicle {
    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; }
}

2. 子類別:Car.java

關鍵在於使用 @hibernate.joined-subclass 標記,並指定連接鍵欄位。

package javamxj.inheritance.two;

/**
 * @hibernate.joined-subclass
 * @hibernate.joined-subclass-key column="id"
 */
public class Car extends Vehicle {
    private String seat;

    /** @hibernate.property column="載客" length="24" */
    public String getSeat() { return seat; }
    public void setSeat(String seat) { this.seat = seat; }
}

3. 子類別:Truck.java

package javamxj.inheritance.two;

/**
 * @hibernate.joined-subclass
 * @hibernate.joined-subclass-key column="id"
 */
public class Truck extends Vehicle {
    private String load;

    /** @hibernate.property column="載重" length="24" */
    public String getLoad() { return load; }
    public void setLoad(String load) { this.load = load; }
}

二、生成映射檔與資料庫 Schema

執行 Ant 任務 generate-hbm,Eclipse 會自動生成 Vehicle.hbm.xml。核心部分為 <joined-subclass> 標籤,它定義了子類別如何通過主鍵關聯到父表。

<hibernate-mapping>
  <class name="javamxj.inheritance.two.Vehicle" ...>
    <id name="id" column="ID"><generator class="hilo"/></id>
    <property name="name" column="name" length="24"/>
    
    <joined-subclass name="javamxj.inheritance.two.Truck">
      <key column="id"/>
      <property name="load" column="載重" length="24"/>
    </joined-subclass>
    
    <joined-subclass name="javamxj.inheritance.two.Car">
      <key column="id"/>
      <property name="seat" column="載客" length="24"/>
    </joined-subclass>
  </class>
</hibernate-mapping>

執行 schemaexport 任務,資料庫將建立三張獨立的表:

  • Vehicle (ID, name)
  • Car (id, 載客)
  • Truck (id, 載重)

子表的主鍵同時也是指向父表的外鍵,實現了正規化的資料結構。

三、測試程式與驗證

編寫 Demo.java 進行資料新增與查詢:

public class Demo {
    public static void main(String[] args) { ... }
    public Demo() throws HibernateException {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        Session sess = sf.openSession();
        Transaction tx = sess.beginTransaction();
        
        Car car = new Car();
        car.setName("奇瑞QQ");
        car.setSeat("4人");
        sess.save(car);
        
        Truck truck = new Truck();
        truck.setName("一汽解放");
        truck.setLoad("10噸");
        sess.save(truck);
        
        tx.commit(); sess.close();
        
        // 多態查詢
        sess = sf.openSession();
        tx = sess.beginTransaction();
        List list = sess.find("from Vehicle");
        for (Iterator it = list.iterator(); it.hasNext();) {
            Vehicle v = (Vehicle) it.next();
            System.out.println("車型:" + v.getName() + " 實際類別:" + v.getClass().getName());
        }
        tx.commit(); sess.close();
    }
}

控制台輸出將顯示正確的子類別型別,證明多態查詢運作正常。

四、策略優缺點總結

優點缺點
  • 最符合面向物件設計,完美支援多態
  • 修改基類、新增子類容易
  • 空間利用率高,無冗餘欄位
  • 資料庫表數量多,結構較複雜
  • 查詢需多表聯結,效能隨繼承層次增加而下降
  • 報表查詢不便,通常需建立視圖

下一篇將介紹「每個具體類一張表」的策略,敬請期待。

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