Lista över samlingar

Tja, du har sett hur man kartlägger enkla typer. Nu är det dags att gå vidare till mer intressanta frågor – hur man kartlägger samlingar av föremål.

Och vi kan ha objekt i 5 grupper:

  • Array - en array av objekt
  • Lista - lista över objekt
  • Uppsättning - uppsättning objekt
  • Karta - en ordbok över objekt
  • Samling - en samling föremål

Och ett exempel på en klass med ett samlingsfält:

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

   @magical-annotation
   public List messages;
}

Så vad är denna magiska anteckning som gör att vi kan lagra inte ett fält, utan många värden?

Den här kommentaren kallas @ElementCollection . Exempel:

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

   @ElementCollection
   public List<String> messages;
}

Det är väldigt enkelt skrivet, men det fungerar icke-trivialt.

Hjälpbord

Alla fält i klassen Entity som innehåller många element och är markerade med @ElementCollection -anteckningen finns i databasen i en speciell hjälptabell. Vilket faktiskt är logiskt.

Den här tabellen kan innehålla data i två former:

  • Ordnat (lista, karta) innehåller tre kolumner:
    • Nyckelkolumn (utländsk nyckel) – referens till det överordnade objektets ID.
    • Indexkolumn - position/index i samlingen.
    • Element Kolumn - värde.
  • Oordnad (uppsättning) innehåller två kolumner:
    • Nyckelkolumn (utländsk nyckel) – referens till det överordnade objektets ID.
    • Element Kolumn - värde.

Du kan också ange namnet på den här tabellen uttryckligen med en anteckning:

@CollectionTable(name="table_name")

Exempel:

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

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

Viktig! Om @CollectionTable- anteckningen inte är specificerad kommer Hibernate att bygga själva tabellnamnet baserat på klassnamnet och fältnamnet: User class och fältetmeddelandennamnge tabellen "User_messages".

Samling Samling

Men låt oss inte lämna skapandet av hjälpbordet till Hibernate och skapa det själva. Först måste vi skapa en tabell med två kolumner:

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

Observera att den här tabellen inte har en egen id-kolumn. Detta är huvudfunktionen hos extra tabeller. Du kommer att bekanta dig med andra typer av extrabord lite senare.

Nu måste vi mappa den här tabellen till vårt fältmeddelandeni klassen Användare . Detta kommer att se ut så här:

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

Här är det värt att uppmärksamma två saker.

Först är meddelandekolumnen, specificerad med @Column(name = "meddelande") annotation , i hjälptabellen user_message, inte användartabellen.

För det andra, i @JoinColumn(name = "user_id") annotation , angav vi namnet på kolumnen user_id, som refererar till användartabellens ID. Detta för att Hibernate ska kunna kombinera dem korrekt.

Samling

Om du vill lagra de ordnade elementen i en lista eller array i en hjälptabell, behöver du en tabell med tre kolumner:

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

Om du inte gillar kolumnnamnet "index", eller om du inte kan ändra det, kan du ange ett annat namn under mappningen. För att göra detta måste du använda @Index- kommentaren .

Exempel:

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

Kartsamling

Och slutligen vill du lagra inte bara en samling, utan en HashMap, och du behöver två kolumner i en extra tabell för det:

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

För att ange en nyckel för en karta behöver du @MapKeyColumn -kommentaren .

Exempel:

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

Du kan hitta mer information i den officiella dokumentationen .