1. Список колекцій
Що ж, ми познайомилися з тим, як мапити прості типи. Тепер настав час перейти до питань цікавіше — як мапити колекції об'єктів.
А об'єкти у нас можуть бути у 5 групах:
- Array — масив об'єктів
- List — список об'єктів
- Set — множина об'єктів
- Map — словник об'єктів
- Collection — колекція об'єктів
І приклад класу з полем-колекцією:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@Чарівна-анотація
public List<String> messages;
}
То що ж це за чарівна анотація така, яка дозволить нам зберігати не одне поле, а багато значень?
Ця анотація називається @ElementCollection. Приклад:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
public List<String> messages;
}
Пишеться вона дуже просто, а ось працює нетривіально.
2. Допоміжна таблиця
Всі поля Entity-класу, які містять багато елементів і позначаються за допомогою анотації @ElementCollection містяться в базі даних у спеціальній допоміжній таблиці. Що, власне, логічно.
Ця таблиця може містити дані у двох форматах:
- Упорядковані (List, Map) містять три колонки:
- Key Column (Foreign Key) — посилання на ID об'єкта-батька.
- Index Column — позиція/індекс у колекції.
- Element Column — значення.
- Неупорядковані (Set) містять дві колонки:
- Key Column (Foreign Key) — посилання на ID об'єкта-батька.
- Element Column — значення.
Також ти можеш зазначити ім'я цієї таблиці явно за допомогою анотації:
@CollectionTable(name="ім'я_таблиці")
Приклад:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
@CollectionTable(name="user_message")
public List<String> messages;
}
Важливо! Якщо анотація @CollectionTable не вказана, то Hibernate сам побудує ім'я таблиці на основі імені класу та імені поля: клас User та поле messages дадуть ім'я таблиці "User_messages".
3. Колекція Set
Але давай не віддаватимемо на відкуп Hibernate створення допоміжної таблиці та зробимо її самі. Спочатку нам потрібно створити таблицю із двома колонками:
CREATE TABLE user_message {
user_id INT,
message VARCHAR(255)
};
Зверни увагу, що ця таблиця не має своєї id-колонки. Це і є основною ознакою допоміжних таблиць. З іншими видами допоміжних таблиць ти познайомишся трохи згодом.
Тепер потрібно замапитти цю таблицю на наше поле messages у класі User. Виглядатиме ця справа так:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
@CollectionTable(name="user_message", joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "message")
public Set<String> messages;
}
Тут варто звернути увагу на дві речі.
По-перше, колонка message, вказана за допомогою анотації @Column(name = "message") знаходиться в допоміжній таблиці user_message, а не в таблиці user.
По-друге, в анотації @JoinColumn(name = "user_id") ми вказали ім'я колонки user_id, який посилається на id таблиці user. Це для того, щоб Hibernate знав, як їх правильно об'єднувати.
4. Колекція List
Якщо ти хочеш зберігати у допоміжній таблиці впорядковані елементи списку чи масиву, то тобі знадобиться таблиця з трьома колонками:
CREATE TABLE user_message {
user_id INT,
index INT,
message VARCHAR(255)
};
Якщо не подобається ім'я колонки "index", або ти не можеш його змінити, можна вказати інше ім'я під час мапінгу. Для цього потрібно використовувати анотацію @Index.
Приклад:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
@CollectionTable(name="user_message",
indexes = { @Index(columnList = "list_index") },
joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "message")
public List<String> messages;
}
5. Колекція Map
І нарешті, ти хочеш зберігати не просто колекцію, а HashMap, і тобі для нього потрібні дві колонки у допоміжній таблиці:
CREATE TABLE user_message {
user_id INT,
key VARCHAR(255),
message VARCHAR(255)
};
Щоб вказати ключ для Map тобі знадобиться анотація @MapKeyColumn.
Приклад:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
@CollectionTable(name="user_message", joinColumns = @JoinColumn(name = "user_id"))
@MapKeyColumn(name = "key")
@Column(name = "message")
public Map<String, String> messages;
}
Детальнішу інформацію ти зможеш знайти в офіційній документації.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ