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まず、すべてのテーブルからデータを選択し、次にそれらの行を で結合し、その後でのみフィルターする必要があるためです。