描述

在上一課中,您看到 Hibernate 使用特殊的 DTYPE VARCHAR 列來存儲實體類的名稱。這樣的列稱為鑑別器。它用於明確確定為數據庫中的給定行創建哪個類。

您可以使用@DiscriminatorColumn註釋操作此列。例子:

@DiscriminatorColumn(name="column_name",   discriminatorType = DiscriminatorType.INTEGER)

根據 JPA 規範,鑑別器可以有以下類型:

  • 細繩
  • 字符
  • 整數

但是,Hibernate 允許您稍微擴展此列表。它支持這些 Java 類型:String、char、int、byte、short、boolean。

如果我們使用INTEGER類型,那麼Entity類的名字怎麼編碼呢?為此,使用了另一個註解—— @DiscriminatorValue

看一個例子:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type",   discriminatorType = DiscriminatorType.INTEGER)
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}
@Entity
@DiscriminatorValue("1")
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}
@Entity
@DiscriminatorValue("2")
class Client extends User {
   String address;
}

在上面的示例中,我們告訴 Hibernate 鑑別器將使用 user_type 列,該列將存儲數字。如果存儲值1,則表示行類型為Employee,如果存儲2,則表示行類型為Client。簡單而美麗。

@DiscriminatorValue

但這還不是全部。您可以告訴 Hibernate 在鑑別符為 NULL 時如何解釋字符串的類型。

其實很簡單。您為@DiscriminatorValue annotation指定空值。例如,像這樣:

@DiscriminatorValue("null")

類示例:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type",   discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("null")
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}

我們已經告訴 Hibernate,任何在 user_type 列中具有 NULL 的表行都應該被解釋為 User 類型的對象。

但這還不是全部。@DiscriminatorValue 註釋還有另一個有趣的值。

這是這個:

@DiscriminatorValue("not null")

類示例:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type",   discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("not null")
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}

通過這個註釋,我們告訴 Hibernate 任何在 user_type 列中具有非 NULL 值的表行都應該被解釋為 User 類型的對象。但這僅適用於未找到明確指定所需數量的類的情況。

對於鑑別器的不同值,它是這樣工作的:

  • 0 - 創建用戶類型的對象
  • 1 - 創建一個Employee類型的對象
  • 2 - 創建一個客戶端類型的對象
  • 3 - 創建一個用戶類型的對象
  • 4 - 創建一個用戶類型的對象

@DiscriminatorFormula

但這還不是全部。對於我們的鑑別器,我們可以指定一個整數公式,它將通過該公式計算@DiscriminatorValue註釋的值。

為此有一個特殊的註釋,稱為@DiscriminatorFormula

例子:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type",   discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorFormula("case when ‘join’ is not null then 1 else 2 end")
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}
@Entity
@DiscriminatorValue("1")
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}
@Entity
@DiscriminatorValue("2")
class Client extends User {
   String address;
}

@DiscriminatorFormula返回的值將由 Hibernate 與@DiscriminatorValue註解中指定的值進行比較。有了它,你可以編寫相當複雜的場景:

@DiscriminatorFormula(
           	"case when address is not null " +
           	"then 'Client' " +
           	"else (" +
           	"   case when occupation is not null " +
           	"   then 'Employee' " +
           	"   else 'Unknown' " +
           	"   end) " +
           	"end "
)