Списък на колекциите
Е, видяхте How да картографирате прости типове. Сега е време да преминем към по-интересни въпроси - How да картографирате колекции от обекти.
И можем да имаме обекти в 5 групи:
- Масив – масив от обекти
- Списък - списък с обекти
- Комплект - набор от обекти
- Карта - речник на обектите
- Колекция - колекция от предмети
И пример за клас с поле за събиране:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@magical-annotation
public List messages;
}
И така, Howва е тази магическа анотация, която ще ни позволи да съхраняваме не едно поле, а много стойности?
Тази анотация се нарича @ElementCollection . Пример:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
public List<String> messages;
}
Написано е много просто, но работи нетривиално.
Помощна маса
Всички полета на класа Entity, които съдържат много елементи и са маркирани с анотацията @ElementCollection , се съдържат в базата данни в специална спомагателна table. Което всъщност е логично.
Тази table може да съдържа данни в две форми:
- Подредените (списък, карта) съдържат три колони:
- Ключова колона (чужд ключ) – препратка към идентификатора на родителския обект.
- Индексна колона - позиция/индекс в колекцията.
- Елемент Колона - стойност.
- Unordered (Set) съдържа две колони:
- Ключова колона (чужд ключ) – препратка към идентификатора на родителския обект.
- Елемент Колона - стойност.
Можете също да зададете името на тази table изрично, като използвате анотация:
@CollectionTable(name="table_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 ще изгради самото име на tableта въз основа на името на класа и името на полето: потребителският клас и полетосъобщениянаименувайте tableта "User_messages".
Колекция Колекция
Но нека не оставяме създаването на помощната table на Hibernate и да я създадем сами. Първо трябва да създадем table с две колони:
CREATE TABLE user_message {
user_id INT,
message VARCHAR(255)
};
Обърнете внимание, че тази table няма собствена id-колона. Това е основната характеристика на помощните таблици. С други видове помощни маси ще се запознаете малко по-късно.
Сега трябва да картографираме тази table към нашето полесъобщенияв потребителския клас . Това ще изглежда така:
@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;
}
Тук си струва да обърнете внимание на две неща.
Първо, колоната за съобщения, посочена с анотацията @Column(name = "message") , е в спомагателната table user_message, а не в tableта user.
Второ, в анотацията @JoinColumn(name = "user_id") посочихме името на колоната user_id, която препраща към идентификатора на потребителската table. Това е така, за да може Hibernate да знае How да ги комбинира правилно.
колекция
Ако искате да съхранявате подредените елементи от списък or масив в спомагателна table, тогава ви е необходима table с три колони:
CREATE TABLE user_message {
user_id INT,
index INT,
message VARCHAR(255)
};
Ако не харесвате името на колоната „индекс“ or не можете да го промените, можете да посочите различно име по време на картографирането. За да направите това, трябва да използвате анотацията @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;
}
Колекция от карти
И накрая, искате да съхранявате не само колекция, но HashMap и имате нужда от две колони в спомагателна table за това:
CREATE TABLE user_message {
user_id INT,
key VARCHAR(255),
message VARCHAR(255)
};
За да посочите ключ за карта, имате нужда от анотацията @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;
}
Можете да намерите повече информация в официалната documentация .
GO TO FULL VERSION