Lista colecțiilor

Ei bine, ați văzut cum să mapați tipuri simple. Acum este timpul să trecem la întrebări mai interesante - cum să cartografiați colecțiile de obiecte.

Și putem avea obiecte în 5 grupuri:

  • Array - o matrice de obiecte
  • Listă - listă de obiecte
  • Set - set de obiecte
  • Harta - un dicționar de obiecte
  • Colecție - o colecție de obiecte

Și un exemplu de clasă cu un câmp de colecție:

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

   @magical-annotation
   public List messages;
}

Deci, ce este această adnotare magică care ne va permite să stocăm nu un câmp, ci multe valori?

Această adnotare se numește @ElementCollection . Exemplu:

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

   @ElementCollection
   public List<String> messages;
}

Este scris foarte simplu, dar funcționează non-trivial.

Masa auxiliara

Toate câmpurile din clasa Entity care conțin multe elemente și sunt marcate cu adnotarea @ElementCollection sunt conținute în baza de date într-un tabel auxiliar special. Ceea ce, de fapt, este logic.

Acest tabel poate conține date în două forme:

  • Ordonate (Lista, Harta) conțin trei coloane:
    • Coloană cheie (cheie străină) – referință la ID-ul obiectului părinte.
    • Coloana Index - poziție/index în colecție.
    • Coloana Element - valoare.
  • Neordonat (Set) conține două coloane:
    • Coloană cheie (cheie străină) – referință la ID-ul obiectului părinte.
    • Coloana Element - valoare.

De asemenea, puteți seta numele acestui tabel în mod explicit folosind o adnotare:

@CollectionTable(name="table_name")

Exemplu:

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

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

Important! Dacă adnotarea @CollectionTable nu este specificată, atunci Hibernate va construi numele tabelului însuși pe baza numelui clasei și a numelui câmpului: clasa User și câmpulmesajedenumește tabelul „Mesaje_utilizator”.

Colecția Colecție

Dar să nu lăsăm crearea tabelului auxiliar pe seama Hibernatei și să o creăm noi înșine. Mai întâi trebuie să creăm un tabel cu două coloane:

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

Rețineți că acest tabel nu are propria sa coloană ID. Aceasta este caracteristica principală a meselor auxiliare. Veți face cunoștință cu alte tipuri de mese auxiliare puțin mai târziu.

Acum trebuie să mapam acest tabel la câmpul nostrumesajeîn clasa User . Acesta va arăta astfel:

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

Aici merită să acordați atenție la două lucruri.

În primul rând, coloana mesaj, specificată cu adnotarea @Column(name = "message") , se află în tabelul auxiliar user_message, nu în tabelul user.

În al doilea rând, în adnotarea @JoinColumn(name = "user_id") , am specificat numele coloanei user_id, care se referă la id-ul tabelului user. Acest lucru este pentru ca Hibernate să știe cum să le combine corect.

Colectie

Dacă doriți să stocați elementele ordonate ale unei liste sau ale unei matrice într-un tabel auxiliar, atunci aveți nevoie de un tabel cu trei coloane:

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

Dacă nu vă place numele coloanei „index” sau nu îl puteți schimba, puteți specifica un alt nume în timpul mapării. Pentru a face acest lucru, trebuie să utilizați adnotarea @Index .

Exemplu:

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

Colecția de hărți

Și, în sfârșit, doriți să stocați nu doar o colecție, ci și un HashMap și aveți nevoie de două coloane într-un tabel auxiliar pentru aceasta:

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

Pentru a specifica o cheie pentru o hartă, aveți nevoie de adnotarea @MapKeyColumn .

Exemplu:

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

Puteți găsi mai multe informații în documentația oficială .