Elenco delle collezioni

Bene, hai visto come mappare i tipi semplici. Ora è il momento di passare a domande più interessanti: come mappare raccolte di oggetti.

E possiamo avere oggetti in 5 gruppi:

  • Array : un array di oggetti
  • Elenco - elenco di oggetti
  • Set - insieme di oggetti
  • Mappa - un dizionario di oggetti
  • Collezione - una collezione di oggetti

E un esempio di una classe con un campo di raccolta:

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

   @magical-annotation
   public List messages;
}

Quindi qual è questa annotazione magica che ci permetterà di memorizzare non un campo, ma molti valori?

Questa annotazione è chiamata @ElementCollection . Esempio:

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

   @ElementCollection
   public List<String> messages;
}

È scritto in modo molto semplice, ma funziona in modo non banale.

Tavolo ausiliario

Tutti i campi della classe Entity che contengono molti elementi e sono contrassegnati con l' annotazione @ElementCollection sono contenuti nel database in una speciale tabella ausiliaria. Il che, in effetti, è logico.

Questa tabella può contenere dati in due forme:

  • Ordinato (Elenco, Mappa) contiene tre colonne:
    • Colonna chiave (chiave esterna): riferimento all'ID dell'oggetto padre.
    • Colonna indice - posizione/indice nella raccolta.
    • Elemento Colonna - valore.
  • Unordered (Set) contiene due colonne:
    • Colonna chiave (chiave esterna): riferimento all'ID dell'oggetto padre.
    • Elemento Colonna - valore.

Puoi anche impostare il nome di questa tabella in modo esplicito utilizzando un'annotazione:

@CollectionTable(name="table_name")

Esempio:

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

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

Importante! Se l' annotazione @CollectionTable non è specificata, Hibernate costruirà il nome della tabella stesso in base al nome della classe e al nome del campo: la classe Utente e il campomessaggidenominare la tabella "Messaggi_utente".

Collezione Collezione

Ma non lasciamo la creazione della tabella ausiliaria a Hibernate e creiamola noi stessi. Per prima cosa dobbiamo creare una tabella con due colonne:

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

Si noti che questa tabella non ha una propria colonna id. Questa è la caratteristica principale delle tabelle ausiliarie. Conoscerai altri tipi di tabelle ausiliarie un po 'più tardi.

Ora dobbiamo mappare questa tabella al nostro campomessagginella classe Utente . Questo sarà simile a questo:

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

Qui vale la pena prestare attenzione a due cose.

Innanzitutto, la colonna del messaggio, specificata con l' annotazione @Column(name = "message") , si trova nella tabella ausiliaria user_message, non nella tabella utente.

In secondo luogo, nell'annotazione @JoinColumn(name = "user_id") , abbiamo specificato il nome della colonna user_id, che fa riferimento all'id della tabella utente. Questo è così che Hibernate sa come combinarli correttamente.

Collezione

Se vuoi memorizzare gli elementi ordinati di un elenco o di un array in una tabella ausiliaria, allora hai bisogno di una tabella con tre colonne:

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

Se non ti piace il nome della colonna "indice" o non puoi cambiarlo, puoi specificare un nome diverso durante la mappatura. Per fare ciò, è necessario utilizzare l' annotazione @Index .

Esempio:

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

Collezione di mappe

E infine, vuoi memorizzare non solo una raccolta, ma una HashMap, e per questo hai bisogno di due colonne in una tabella ausiliaria:

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

Per specificare una chiave per una mappa, è necessaria l' annotazione @MapKeyColumn .

Esempio:

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

Puoi trovare maggiori informazioni nella documentazione ufficiale .