Lista kolekcji

Cóż, widziałeś, jak odwzorowywać proste typy. Teraz czas przejść do bardziej interesujących pytań - jak mapować kolekcje obiektów.

I możemy mieć obiekty w 5 grupach:

  • Tablica - tablica obiektów
  • Lista - lista obiektów
  • Zestaw - zestaw obiektów
  • Mapa - słownik obiektów
  • Kolekcja - kolekcja obiektów

I przykład klasy z polem kolekcji:

@Entity
@Table(name="user")
class User {
   @Id
   @Column(name="id")
   public Integer id;

   @magical-annotation
   public List messages;
}

Czym więc jest ta magiczna adnotacja, która pozwoli nam przechowywać nie jedno pole, a wiele wartości?

Ta adnotacja nosi nazwę @ElementCollection . Przykład:

@Entity
@Table(name="user")
class User  {
   @Id
   @Column(name="id")
   public Integer id;

   @ElementCollection
   public List<String> messages;
}

Jest napisany bardzo prosto, ale działa nietrywialnie.

Stół pomocniczy

Wszystkie pola klasy Entity, które zawierają wiele elementów i są oznaczone adnotacją @ElementCollection , zawarte są w bazie danych w specjalnej tabeli pomocniczej. Co w gruncie rzeczy jest logiczne.

Ta tabela może zawierać dane w dwóch postaciach:

  • Uporządkowane (Lista, Mapa) zawierają trzy kolumny:
    • Kolumna klucza (klucz obcy) – odniesienie do identyfikatora obiektu nadrzędnego.
    • Kolumna indeksu - pozycja/indeks w kolekcji.
    • Kolumna elementu - wartość.
  • Nieuporządkowane (zestaw) zawiera dwie kolumny:
    • Kolumna klucza (klucz obcy) – odniesienie do identyfikatora obiektu nadrzędnego.
    • Kolumna elementu - wartość.

Możesz także jawnie ustawić nazwę tej tabeli, używając adnotacji:

@CollectionTable(name="table_name")

Przykład:

@Entity
@Table(name="user")
class User {
   @Id
   @Column(name="id")
   public Integer id;

   @ElementCollection
   @CollectionTable(name="user_message")
   public List<String> messages;
}

Ważny! Jeśli adnotacja @CollectionTable nie zostanie określona, ​​Hibernate zbuduje samą nazwę tabeli na podstawie nazwy klasy i nazwy pola: klasa użytkownika i polewiadomościnazwij tabelę „User_messages”.

Kolekcja Kolekcja

Ale nie zostawiajmy tworzenia tabeli pomocniczej Hibernacji i stwórzmy ją sami. Najpierw musimy utworzyć tabelę z dwiema kolumnami:

CREATE TABLE user_message {
    user_id INT,
    message VARCHAR(255)
};

Zauważ, że ta tabela nie ma własnej kolumny id. Jest to główna cecha stołów pomocniczych. Nieco później zapoznasz się z innymi typami stołów pomocniczych.

Teraz musimy zmapować tę tabelę do naszego polawiadomościw klasie Użytkownika . To będzie wyglądać tak:

@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;
}

Tutaj warto zwrócić uwagę na dwie rzeczy.

Po pierwsze, kolumna komunikatu określona adnotacją @Column(name = "message") znajduje się w tabeli pomocniczej user_message, a nie w tabeli user.

Po drugie, w adnotacji @JoinColumn(name = "user_id") podaliśmy nazwę kolumny user_id, która odnosi się do id tabeli user. Dzieje się tak, aby Hibernate wiedział, jak poprawnie je połączyć.

Kolekcja

Jeśli chcesz przechowywać uporządkowane elementy listy lub tablicy w tabeli pomocniczej, potrzebujesz tabeli z trzema kolumnami:

CREATE TABLE user_message {
    user_id INT,
    index INT,
    message VARCHAR(255)
};

Jeśli nie podoba Ci się nazwa kolumny „indeks” lub nie możesz jej zmienić, możesz określić inną nazwę podczas mapowania. Aby to zrobić, musisz użyć adnotacji @Index .

Przykład:

@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;
}

Kolekcja map

I wreszcie, chcesz przechowywać nie tylko kolekcję, ale HashMap i potrzebujesz do tego dwóch kolumn w tabeli pomocniczej:

CREATE TABLE user_message {
    user_id INT,
    key VARCHAR(255),
    message VARCHAR(255)
};

Aby określić klucz dla mapy, potrzebujesz adnotacji @MapKeyColumn .

Przykład:

@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;
}

Więcej informacji można znaleźć w oficjalnej dokumentacji .