描述
在上一課中,您看到 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 "
)