描述

上述每種策略和技術都有其自身的優點和缺點。選擇特定策略的一般建議如下所示:

基於 UNION 的 TABLE_PER_CLASS 策略

如果不需要多態查詢和關聯,則最好選擇此策略。如果您很少做(或根本不做)“從用戶用戶中選擇用戶”。如果您沒有引用用戶的實體類,這是最好的選擇(因為您仍然可以添加優化的多態查詢和關聯)。

SINGLE_TABLE 策略

應使用此策略:

a) 僅適用於簡單任務。在規範化和 NOT NULL 約束至關重要的情況下,應該首選策略 #3 (JOINED)。思考在這種情況下是否不值得完全放棄繼承而代之以委託是有道理的。

b) 如果需要多態查詢和關聯,以及在運行時動態定義具體類。同時,子類聲明的新字段相對較少,與超類的主要區別在於行為。

最重要的是,您與 DBA 進行了認真的對話。

加盟戰略

這種策略在速度和約束方面是最有效的。適用於需要多態查詢和關聯,但子類聲明新字段較多的情況。

這裡要提醒一句:JOINED 和 TABLE_PER_CLASS 之間的決定需要對真實數據的查詢執行計劃進行評估,因為繼承層次結構的寬度和深度會使連接成本(以及性能)變得無法接受。

另外,值得考慮的是,繼承註解不能應用於接口。

明確的

還可能存在這樣一種情況,即您在數據庫中具有實體類層次結構和共享存儲策略。但無論出於何種原因,您都不希望在對基類進行查詢時返回某個層次結構類。

有一個註釋:

@Polymorphism(type = PolymorphismType.EXPLICIT)

如果我們將它添加到Client類:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}
@Entity
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}
@Entity
@Polymorphism(type = PolymorphismType.EXPLICIT)
class Client extends User {
   String address;
}

那麼HQL查詢在查詢基類時會忽略這個類的對象:

List<User> accounts = session.createQuery("from User").getResultList();

此查詢將返回UserEmployee對象的列表,但不返回Client