Список колекцій
Що ж, ти познайомився з тим, як мапит прості типи. Тепер настав час перейти до питань цікавіше – як мапити колекції об'єктів.
А об'єкти у нас можуть бути у 5 групах:
- Array – масив об'єктів
- List – список об'єктів
- Set - безліч об'єктів
- Map – словник об'єктів
- Collection – колекція об'єктів
І приклад класу із полем-колекцією:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@Чарівна-анотація
public List messages;
}
То що ж це за чарівна інструкція така, яка дозволить нам зберігати не одне поле, а багато значень?
Ця інструкція називається @ElementCollection . Приклад:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
public List<String> messages;
}
Пишеться вона дуже просто, а от працює нетривіально.
Допоміжна таблиця
Усі поля 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".
Колекція 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 знав, як їх правильно поєднувати.
Колекція 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;
}
Колекція 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;
}
Більш детальну інформацію ти зможеш знайти в офіційній документації .
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ