1. Зв'язок на рівні таблиць
Давай знову розглянемо дві наші таблиці:
id | name | occupation | salary | age | join_date |
---|---|---|---|---|---|
1 | Шевченко Ігор | Програміст | 100000 | 25 | 2012-06-30 |
2 | Коваленко Максим | Програміст | 80000 | 23 | 2013-08-12 |
3 | Шевченко Данило | Тестувальник | 40000 | 30 | 2014-01-01 |
4 | Мельник Степан | Директор | 200000 | 35 | 2015-05-12 |
5 | Кірієнко Анастасія | Офіс-менеджер | 40000 | 25 | 2015-10-10 |
6 | Пончик | Кіт | 1000 | 3 | 2018-11-11 |
Таблиця employee:
У цій таблиці є такі колонки:
- id INT
- name VARCHAR
- occupation VARCHA
- salary INT
- age INT
- join_date DATE
А так виглядає таблиця task, яка містить завдання для співробітників:
id | emploee_id | name | deadline |
---|---|---|---|
1 | 1 | Виправити багу на фронтенді | 2022-06-01 |
2 | 2 | Виправити багу на бекенді | 2022-06-15 |
3 | 5 | Купити каву | 2022-07-01 |
4 | 5 | Купити каву | 2022-08-01 |
5 | 5 | Купити каву | 2022-09-01 |
6 | (NULL) | Прибрати офіс | (NULL) |
7 | 4 | Насолоджуватися життям | (NULL) |
8 | 6 | Насолоджуватися життям | (NULL) |
У цій таблиці є лише 4 колонки:
- id — унікальний номер завдання (та рядки у таблиці).
- employee_id — ID співробітника з таблиці employee, на якого призначено завдання.
- name — назва та опис завдання.
- deadline — час, до якого потрібно виконати завдання.
На один запис таблиці employee можуть посилатися багато рядків таблиці task. Такий зв'язок на рівні таблиць називається один-до-багатьох (one-to-many).
2. Зв'язок на рівень Java-класів
І наші класи, клас Employee:
@Entity
@Table(name="user")
class Employee {
@Column(name="id")
public Integer id;
@Column(name="name")
public String name;
@Column(name="occupation")
public String occupation;
@Column(name="salary")
public Integer salary;
@Column(name="join_date")
public Date join;
}
І клас EmployeeTask у його первісному вигляді:
@Entity
@Table(name="task")
class EmployeeTask {
@Column(name="id")
public Integer id;
@Column(name="name")
public String description;
@Column(name="employee_id")
public Integer employeeId;
@Column(name="deadline")
public Date deadline;
}
3. Аннотація @OneToMany
Ми можемо організувати зв'язок Entity-класів по-іншому.
Пам'ятаєш анотацію @ElementCollection, за допомогою якої ми в батьківському класі створювали колекцію дочірніх об'єктів? Щось схоже можна зробити за допомогою анотації @OneToMany. Лише цього разу зміни зазнають клас Employee:
@Entity
@Table(name="user")
class Employee {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "employee_id")
private Set<EmployeeTask> tasks = new HashSet<EmployeeTask>();
}
За допомогою анотації @OneToMany ми вказали, що об'єкт Employee може зберігати багато об'єктів EmployeeTask. Також за допомогою анотації @JoinColumn ми вказали, в якій колонці таблиці task зберігається id об'єкта Employee.
Водночас клас EmployeeTask зазвичай не містить поля, яке посилається на колонку employee_id. Приклад:
@Entity
@Table(name="task")
class EmployeeTask {
@Column(name="id")
public Integer id;
@Column(name="name")
public String description;
@Column(name="deadline")
public Date deadline;
}
Поле employee_id вважається службовим, і його значенням управляє Hibernate.
4. Приклади запитів
Якщо ти хочеш додати якомусь працівникові певний task, то тобі потрібно написати код типу:
EmployeeTask task1 = новий EmployeeTask();
task1.description = "Зробити щось важливе";
session.persist(task1);
EmployeeTask task2 = новий EmployeeTask();
task2.description = "Нічого не робити";
session.persist(task2);
session.flush();
Employee director = session.find(Employee.class, 4);
director.tasks.add(task1);
director.tasks.add(task2);
session.update(director);
session.flush();
Спочатку ми створюємо два об'єкти EmployeeTask, зберігаємо їх до бази та викликаємо метод flush(), щоб виконалася операція INSERT і в об'єктів з'явилися ID.
Потім знаходимо в базі директора, беремо в нього поле tasks і додаємо йому два завдання. Потім зберігаємо директора до бази. Після цього в базі нових task в колонці employee_id з'явиться значення 4 — id директора в таблиці employee.
Важливо! Таблиці в базі однакові для анотацій @ManyToOne та @OneToMany. А ось Java-класи для цих таблиць — різні.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ