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