5.1 说明
最后,最后一个策略是每类表。这意味着每个类将使用一个单独的表。从某种意义上说,这是同一个 MappedSuperClass,只是更新了形式。
首先,您需要使用注释:
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
带有此注释的类将如下所示:
@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
class Client extends User {
String address;
}
并为每个班级单独的表格。例如,这些:
CREATE TABLE user {
id INT,
name VARCHAR,
birthday DATE
}
CREATE TABLE employee {
id INT,
name VARCHAR,
birthday DATE,
occupation VARCHAR,
salary INT,
join DATE
}
CREATE TABLE client {
id INT,
name VARCHAR,
birthday DATE,
address VARCHAR
}
主要区别在于传递 id (PRIMARY KEY) 用于所有表。您不能有具有相同 id 的不同行,不仅在同一个表中,而且在这组表中。Hibernate 会处理这个。
5.2 例子
看看这一切是如何运作的非常有趣。
您可以编写一个简单的 HQL 查询来获取所有用户:User、Employee、Client:
List<User> accounts = session.createQuery("from User").list();
但是 Hibernate 反过来会生成一个非常有趣的查询。它会从所有表中进行选择,然后通过 UNION ALL 将其组合成一种虚拟表,然后才会搜索和/或选择
但是为了合并不同列的表,首先需要补充假列。比如user表需要补充列:
occupation VARCHAR
salary INT
join DATE
address VARCHAR
执行前对用户表的 SQL 查询示例UNION ALL
:
SELECT id,
name,
birthday,
CAST(NULL AS VARCHAR) AS occupation,
CAST(NULL AS INT) AS salary,
CAST(NULL AS DATE) AS join,
CAST(NULL AS VARCHAR) AS address,
0 AS clazz
FROM user
执行前对员工表的SQL 查询示例UNION ALL
:
SELECT id,
name,
birthday,
occupation,
salary,
join,
CAST(NULL AS VARCHAR) AS address,
1 AS clazz
FROM employee
执行前对客户端表的 SQL 查询示例UNION ALL
:
SELECT id,
name,
birthday,
CAST(NULL AS VARCHAR) AS occupation,
CAST(NULL AS INT) AS salary,
CAST(NULL AS DATE) AS join,
address,
2 AS clazz
FROM client
好消息是 HQL 查询将按照您希望的方式工作。
坏消息是,如果表中有大量数据,它们可能会很慢。因为首先你需要从所有表中选择数据,然后将它们的行与 合并UNION ALL
,然后才进行过滤。
GO TO FULL VERSION