5.1 Beskrivelse
Og til slutt, den siste strategien er Tabell per klasse. Det betyr at en egen tabell vil bli brukt for hver klasse. På en måte er dette den samme MappedSuperClass, bare i en oppdatert form.
Først må du bruke en merknad:
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
Klasser med denne merknaden vil se slik ut:
@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;
}
Og separate tabeller for hver klasse. For eksempel disse:
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
}
Hovedforskjellen er at en pass-through id (PRIMARY KEY) brukes for alle tabeller. Du kan ikke ha forskjellige rader med samme id, ikke bare innenfor samme tabell, men også innenfor denne gruppen av tabeller. Hibernate tar seg av dette.
5.2 Eksempler
Det er veldig interessant å se hvordan det hele fungerer.
Du kan skrive en enkel HQL-spørring for å få alle brukere: bruker, ansatt, klient :
List<User> accounts = session.createQuery("from User").list();
Men Hibernate vil på sin side generere en veldig interessant spørring. Den vil gjøre et valg fra alle tabeller, deretter kombinere den gjennom UNION ALL til en slags virtuell tabell, og først da vil den søke og/eller velge
Men for å slå sammen tabeller med forskjellige kolonner, må de først suppleres med falske kolonner. For eksempel må brukertabellen suppleres med kolonner:
occupation VARCHAR
salary INT
join DATE
address VARCHAR
Et eksempel på en SQL-spørring til brukertabellen før kjøring 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
Et eksempel på SQL-spørring til ansatttabellen før utførelse UNION ALL
:
SELECT id,
name,
birthday,
occupation,
salary,
join,
CAST(NULL AS VARCHAR) AS address,
1 AS clazz
FROM employee
Et eksempel på en SQL-spørring til klienttabellen før kjøring 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 gode nyheten er at HQL-spørringer vil fungere slik du vil at de skal.
Den dårlige nyheten er at de kan være trege hvis det er mye data i tabellene. Fordi først må du velge data fra alle tabellene, deretter kombinere radene deres med UNION ALL
, og først deretter filtrere.