5.1 Beskrivning

Och slutligen, den sista strategin är Tabell per klass. Det betyder att en separat tabell kommer att användas för varje klass. På sätt och vis är detta samma MappedSuperClass, bara i en uppdaterad form.

Först måste du använda en anteckning:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Klasser med denna kommentar kommer att se ut så här:


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

Och separata tabeller för varje klass. Till exempel dessa:


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
}

Den största skillnaden är att ett pass-through-id (PRIMARY KEY) används för alla tabeller. Du kan inte ha olika rader med samma id, inte bara inom samma tabell, utan även inom denna grupp av tabeller. Hibernate tar hand om detta.

5.2 Exempel

Det är väldigt intressant att se hur det hela fungerar.

Du kan skriva en enkel HQL-fråga för att få alla användare: användare, anställd, klient :

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

Men Hibernate kommer i sin tur att generera en mycket intressant fråga. Den kommer att göra ett urval från alla tabeller, sedan kombinera det genom UNION ALL till en slags virtuell tabell, och först då kommer den att söka och/eller välja

Men för att slå samman tabeller med olika kolumner måste de först kompletteras med falska kolumner. Användartabellen måste till exempel kompletteras med kolumner:

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

Ett exempel på en SQL-fråga till användartabellen före körning 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

Ett exempel på en SQL-fråga till medarbetartabellen före körning UNION ALL:


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

Ett exempel på en SQL-fråga till klienttabellen före exekvering 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

Den goda nyheten är att HQL-frågor kommer att fungera som du vill att de ska.

Den dåliga nyheten är att de kan vara långsamma om det finns mycket data i tabellerna. För först måste du välja data från alla tabeller, sedan kombinera deras rader med , UNION ALLoch först sedan filtrera.