Списък на колекциите

Е, видяхте 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ация .