รายการคอลเลกชัน

คุณได้เห็นวิธีแมปประเภทอย่างง่ายแล้ว ตอนนี้ถึงเวลาที่จะไปยังคำถามที่น่าสนใจมากขึ้น - วิธีแมปคอลเลกชันของวัตถุ

และเราสามารถมีวัตถุได้ 5 กลุ่ม:

  • Array - อาร์เรย์ของวัตถุ
  • รายการ - รายการวัตถุ
  • ชุด - ชุดของวัตถุ
  • แผนที่ - พจนานุกรมของวัตถุ
  • คอลเลกชัน - คอลเลกชันของวัตถุ

และตัวอย่างคลาสที่มีฟิลด์คอลเลกชัน:

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

   @magical-annotation
   public List messages;
}

ดังนั้นคำอธิบายประกอบที่มีมนต์ขลังนี้จะช่วยให้เราไม่เก็บฟิลด์เดียว แต่มีหลายค่าได้อย่างไร

คำอธิบายประกอบนี้เรียกว่า@ElementCollection ตัวอย่าง:

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

   @ElementCollection
   public List<String> messages;
}

มันเขียนอย่างเรียบง่าย แต่ใช้งานไม่ได้เล็กน้อย

ตารางเสริม

ฟิลด์ทั้งหมดของคลาสเอนทิตีที่มีองค์ประกอบจำนวนมากและทำเครื่องหมายด้วย คำอธิบายประกอบ @ElementCollectionมีอยู่ในฐานข้อมูลในตารางเสริมพิเศษ ซึ่งในความเป็นจริงเป็นตรรกะ

ตารางนี้สามารถบรรจุข้อมูลได้สองรูปแบบ:

  • สั่งซื้อ (รายการ, แผนที่) มีสามคอลัมน์:
    • คอลัมน์คีย์ (Foreign Key) – อ้างอิงถึง ID ของวัตถุหลัก
    • คอลัมน์ดัชนี - ตำแหน่ง/ดัชนีในคอลเลกชัน
    • คอลัมน์องค์ประกอบ - ค่า
  • ไม่มีลำดับ (ชุด) มีสองคอลัมน์:
    • คอลัมน์คีย์ (Foreign Key) – อ้างอิงถึง ID ของวัตถุหลัก
    • คอลัมน์องค์ประกอบ - ค่า

คุณยังสามารถตั้งชื่อตารางนี้อย่างชัดเจนโดยใช้คำอธิบายประกอบ:

@CollectionTable(name="table_name")

ตัวอย่าง:

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

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

สำคัญ! หาก ไม่ได้ระบุคำอธิบายประกอบ @CollectionTableจากนั้น Hibernate จะสร้างชื่อตารางเองตามชื่อคลาสและชื่อฟิลด์: คลาสผู้ใช้และฟิลด์ข้อความตั้งชื่อตารางว่า "User_messages"

คอลเลคชั่น

แต่อย่าปล่อยให้การสร้างตารางเสริมเป็นไฮเบอร์เนตและสร้างเอง ก่อนอื่นเราต้องสร้างตารางที่มีสองคอลัมน์:

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

โปรดทราบว่าตารางนี้ไม่มีคอลัมน์รหัสของตนเอง นี่คือคุณสมบัติหลักของตารางเสริม คุณจะทำความคุ้นเคยกับตารางเสริมประเภทอื่นในภายหลัง

ตอนนี้เราต้องแมปตารางนี้กับฟิลด์ของเราข้อความใน คลาส ผู้ใช้ ซึ่งจะมีลักษณะดังนี้:

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

ที่นี่ควรให้ความสนใจกับสองสิ่ง

อันดับแรก คอลัมน์ข้อความที่ระบุด้วย@Column(name = "message") คำอธิบาย ประกอบ อยู่ในตารางเสริม user_message ไม่ใช่ตารางผู้ใช้

ประการที่สอง ใน คำอธิบายประกอบ @JoinColumn(name = "user_id")เราได้ระบุชื่อของคอลัมน์ user_id ซึ่งอ้างอิงถึง id ของตารางผู้ใช้ เพื่อให้ Hibernate รู้วิธีรวมเข้าด้วยกันอย่างถูกต้อง

ของสะสม

หากคุณต้องการจัดเก็บองค์ประกอบที่เรียงลำดับของรายการหรืออาร์เรย์ในตารางเสริม คุณต้องมีตารางที่มีสามคอลัมน์:

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

หากคุณไม่ชอบชื่อคอลัมน์ "ดัชนี" หรือไม่สามารถเปลี่ยนแปลงได้ คุณสามารถระบุชื่ออื่นระหว่างการแมป ในการทำเช่น นี้คุณต้องใช้ คำอธิบายประกอบ @Index

ตัวอย่าง:

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

คอลเลกชันแผนที่

และสุดท้าย คุณต้องการจัดเก็บไม่เพียงแค่คอลเลกชั่น แต่ต้องมี HashMap และคุณต้องการสองคอลัมน์ในตารางเสริมสำหรับมัน:

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

ในการ ระบุคีย์สำหรับแผนที่ คุณต้องมี คำอธิบายประกอบ @MapKeyColumn

ตัวอย่าง:

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

คุณสามารถค้นหาข้อมูลเพิ่มเติมได้ในเอกสารอย่างเป็นทางการ