5.1 Opis

I wreszcie ostatnia strategia to Table per class. Oznacza to, że dla każdej klasy będzie używana oddzielna tabela. W pewnym sensie jest to ta sama MappedSuperClass, tylko w zaktualizowanej formie.

Najpierw musisz użyć adnotacji:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Klasy z tą adnotacją będą wyglądać następująco:


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

I osobne stoły dla każdej klasy. Na przykład te:


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
}

Główna różnica polega na tym, że dla wszystkich tabel używany jest identyfikator przekazujący (PRIMARY KEY). Nie możesz mieć różnych wierszy o tym samym id, nie tylko w tej samej tabeli, ale także w tej grupie tabel. Hibernate się tym zajmie.

5.2 Przykłady

To bardzo interesujące zobaczyć, jak to wszystko działa.

Możesz napisać proste zapytanie HQL, aby uzyskać wszystkich użytkowników: Użytkownik, Pracownik, Klient :

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

Ale Hibernate z kolei wygeneruje bardzo ciekawe zapytanie. Dokona wyboru ze wszystkich tabel, następnie połączy to przez UNION ALL w coś w rodzaju wirtualnej tabeli i dopiero wtedy wyszuka i / lub wybierze

Aby jednak scalić tabele z różnymi kolumnami, należy je najpierw uzupełnić fałszywymi kolumnami. Na przykład tabelę użytkowników należy uzupełnić o kolumny:

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

Przykład zapytania SQL do tabeli użytkownika przed wykonaniem 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

Przykładowe zapytanie SQL do tabeli pracowników przed wykonaniem UNION ALL:


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

Przykład zapytania SQL do tabeli klienta przed wykonaniem 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

Dobrą wiadomością jest to, że zapytania HQL będą działać tak, jak chcesz.

Zła wiadomość jest taka, że ​​mogą działać wolno, jeśli w tabelach jest dużo danych. Bo najpierw trzeba wybrać dane ze wszystkich tabel, potem połączyć ich wiersze z UNION ALL, a dopiero potem filtrować.