Зв'язок лише на рівні таблиць
Давай знову розглянемо дві наші таблиці:
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 |
Таблиця працівника:
У цій таблиці є такі колонки:
- 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).
Зв'язок на рівень 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;
}
Анотація @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.
Приклади запитів
Якщо ти хочеш додати якомусь працівнику певний task, то тобі потрібно написати код такого:
EmployeeTask task1 = new EmployeeTask();
task1.description = "Зробити щось важливе";
session.persist(task1);
EmployeeTask task2 = new 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-класи для цих таблиць – різні.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ