5.1 Описание

И накрая, последната стратегия е Таблица за клас. Това означава, че за всеки клас ще се използва отделна table. В известен смисъл това е същият 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
}

Основната разлика е, че за всички таблици се използва идентификатор за преминаване (PRIMARY KEY). Не можете да имате различни редове с едно и също id, не само в рамките на една и съща table, но и в тази група от таблици. Hibernate ще се погрижи за това.

5.2 Примери

Много е интересно да се види How работи всичко.

Можете да напишете проста HQL заявка, за да получите всички потребители: потребител, служител, клиент :

List<User> accounts = session.createQuery("from User").list();

Но Hibernate от своя страна ще генерира много интересна заявка. Той ще направи селекция от всички таблици, след това ще ги комбинира чрез UNION ALL в нещо като виртуална table и едва тогава ще търси и/or избира

Но за да обедините таблици с различни колони, те първо трябва да бъдат допълнени с фалшиви колони. Например потребителската table трябва да бъде допълнена с колони:

  • occupation VARCHAR
  • salary INT
  • join DATE
  • address VARCHAR

Пример за SQL заявка към потребителската table преди изпълнение 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 заявка към tableта на служителите преди изпълнение UNION ALL:


SELECT   id,
         name,
         birthday,
         occupation,
         salary,
         join,
         CAST(NULL AS VARCHAR) AS address,
         1 AS clazz
FROM  employee

Пример за SQL заявка към клиентската table преди изпълнение 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 заявките ще работят така, Howто искате.

Лошата новина е, че те могат да бъдат бавни, ако има много данни в таблиците. Защото първо трябва да изберете данни от всички таблици, след това да комбинирате техните редове с UNION ALLи едва след това да филтрирате.