描述
在上一课中,您看到 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 "
)
GO TO FULL VERSION