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ă .
GO TO FULL VERSION