5.1 Descriptif

Et enfin, la dernière stratégie est Table par classe. Cela signifie qu'un tableau distinct sera utilisé pour chaque classe. Dans un sens, il s'agit de la même MappedSuperClass, uniquement sous une forme mise à jour.

Tout d'abord, vous devez utiliser une annotation :

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Les classes avec cette annotation ressembleront à ceci :


@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;
}

Et des tables séparées pour chaque classe. Par exemple, ceux-ci :


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
}

La principale différence est qu'un identifiant de passage (PRIMARY KEY) est utilisé pour toutes les tables. Vous ne pouvez pas avoir différentes lignes avec le même identifiant, non seulement dans la même table, mais également dans ce groupe de tables. Hibernate s'en chargera.

5.2 Exemples

C'est très intéressant de voir comment tout cela fonctionne.

Vous pouvez écrire une simple requête HQL pour obtenir tous les utilisateurs : Utilisateur, Employé, Client :

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

Mais Hibernate, à son tour, va générer une requête très intéressante. Il fera une sélection parmi toutes les tables, puis la combinera via UNION ALL dans une sorte de table virtuelle, et alors seulement il recherchera et / ou sélectionnera

Mais pour fusionner des tables avec des colonnes différentes, elles doivent d'abord être complétées par de fausses colonnes. Par exemple, la table des utilisateurs doit être complétée par des colonnes :

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

Un exemple de requête SQL vers la table utilisateur avant exécution 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

Un exemple de requête SQL vers la table employee avant exécution UNION ALL:


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

Un exemple de requête SQL vers la table client avant exécution 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

La bonne nouvelle est que les requêtes HQL fonctionneront comme vous le souhaitez.

La mauvaise nouvelle est qu'ils peuvent être lents s'il y a beaucoup de données dans les tables. Parce que vous devez d'abord sélectionner les données de toutes les tables, puis combiner leurs lignes avec UNION ALL, et seulement ensuite filtrer.