Опис
Наступний підхід до зберігання ієрархії класів – це зберігати всі класи ієрархії лише у таблиці . Така стратегія називається Single Table .
Наприклад, так:
CREATE TABLE user_ employee_client {
id INT,
name VARCHAR,
birthday DATE,
occupation VARCHAR,
salary INT,
join DATE,
address VARCHAR,
DTYPE VARCHAR
}
Тобто у нас є одна таблиця, яка має колонки для всіх класів нашої ієрархії позначені різними кольорами. Також є спеціальна службова колонка DTYPE VARCHAR , де Hibernate зберігатиме ім'я Entity-класу.
Справа залишилася за малим - пояснити Hibernate, що дані Entity-класів тепер зберігаються в базі однієї таблиці. Зробити це можна за допомогою анотації @Inheritance :
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
Приклад наших класів:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@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;
}
Як дані зберігаються
Тепер давай напишемо приклад, де створимо кілька наших сутностей і збережемо їх в базу:
Employee employee = new Employee();
employee.id = 101;
employee.name = "Іванів";
employee.birthday = LocalDate.of("01-01-1999");
employee.occupation = "Програміст"
employee.salary = 100000;
employee.join = LocalDate.of("12-01-2018");
session.persist(employee);
Client client = new Client();
client.id = 102;
client.name = "Петроів";
client.birthday = LocalDate.of("15-11-1988");
client.address = "Шандара";
session.persist(client);
При збереженні до бази даних буде виконано такий SQL-запит:
INSERT INTO user_ employee_client (id, name, birthday, occupation, salary, join, DTYPE)
VALUES (101, 'Іванів', '01-01-1999', 'Програміст', 100000, '12-01-2018', 'Employee')
INSERT INTO user_ employee_client (id, name, birthday, address, DTYPE)
VALUES (102, 'Петроів', '15-11-1988', 'Шандара', 'Client')
За збереження даних у таблицю Hibernate передає лише відомі йому поля сутностей. Це означає, що невказані колонки матимуть значення NULL.
А це означає, що ти не можеш вказати для стовпчика occupation тип NOT NULL, тому що при зберіганні клієнта в цій же таблиці його occupation буде NULL. Це один із мінусів зберігання різних сутностей в одній таблиці.
Останнє поле SQL-запиті – це колонка DTYPE, у ній передається ім'я Entity-класу. Він використовується Hibernate, коли ти хочеш прочитати дані зі своєї таблиці.
Приклад:
List<User> accounts = session.createQuery("from User").list();
Цей запит поверне список усіх збережених у базі об'єктів типу користувач: User, Employee та Client. На основі колонки DTYPE буде правильно визначено тип сутності та створено об'єкт правильного класу.
У нашому випадку у списку accounts будуть два об'єкти: тип Employee і тип Client.
HQL рулить.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ