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 例
それがどのように機能するのかを見るのは非常に興味深いです。
すべてのユーザー ( User、Employee、Client )を取得する単純な HQL クエリを作成できます。
List<User> accounts = session.createQuery("from User").list();
しかし、Hibernate は非常に興味深いクエリを生成します。すべてのテーブルから選択を行い、それを UNION ALL を介して一種の仮想テーブルに結合し、その後でのみ検索および/または選択を行います。
ただし、異なる列を持つテーブルをマージするには、まず偽の列を追加する必要があります。たとえば、ユーザー テーブルには列を追加する必要があります。
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