Danh sách các bộ sưu tập

Chà, bạn đã thấy cách ánh xạ các loại đơn giản. Bây giờ là lúc chuyển sang các câu hỏi thú vị hơn - cách lập bản đồ các bộ sưu tập đối tượng.

Và chúng ta có thể có các đối tượng trong 5 nhóm:

  • Mảng - một mảng các đối tượng
  • Danh sách - danh sách các đối tượng
  • Set - tập hợp các đối tượng
  • Bản đồ - một từ điển của các đối tượng
  • Bộ sưu tập - một bộ sưu tập các đối tượng

Và một ví dụ về một lớp có trường bộ sưu tập:

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

   @magical-annotation
   public List messages;
}

Vậy chú thích kỳ diệu này sẽ cho phép chúng ta lưu trữ không chỉ một trường mà nhiều giá trị là gì?

Chú thích này được gọi là @ElementCollection . Ví dụ:

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

   @ElementCollection
   public List<String> messages;
}

Nó được viết rất đơn giản, nhưng nó hoạt động không tầm thường.

bàn phụ trợ

Tất cả các trường của lớp Thực thể chứa nhiều phần tử và được đánh dấu bằng chú thích @ElementCollection đều được chứa trong cơ sở dữ liệu trong một bảng phụ trợ đặc biệt. Mà, trên thực tế, là hợp lý.

Bảng này có thể chứa dữ liệu ở hai dạng:

  • Thứ tự (Danh sách, Bản đồ) chứa ba cột:
    • Cột khóa (Khóa ngoại) – tham chiếu đến ID của đối tượng gốc.
    • Cột chỉ mục - vị trí/chỉ mục trong bộ sưu tập.
    • Cột Element - giá trị.
  • Không có thứ tự (Bộ) chứa hai cột:
    • Cột khóa (Khóa ngoại) – tham chiếu đến ID của đối tượng gốc.
    • Cột Element - giá trị.

Bạn cũng có thể đặt tên của bảng này một cách rõ ràng bằng chú thích:

@CollectionTable(name="table_name")

Ví dụ:

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

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

Quan trọng! Nếu chú thích @CollectionTable không được chỉ định, thì Hibernate sẽ tự xây dựng tên bảng dựa trên tên lớp và tên trường: lớp Người dùng và trườngtin nhắnđặt tên cho bảng là "User_messages".

Bộ sưu tập Bộ sưu tập

Nhưng chúng ta đừng để việc tạo bảng phụ trợ cho Hibernate và tự tạo nó. Đầu tiên chúng ta cần tạo một bảng có hai cột:

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

Lưu ý rằng bảng này không có cột id riêng. Đây là tính năng chính của các bảng phụ trợ. Bạn sẽ làm quen với các loại bảng phụ khác sau một chút.

Bây giờ chúng ta cần ánh xạ bảng này vào trường của chúng tatin nhắntrong lớp Người dùng . Điều này sẽ trông như thế này:

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

Ở đây đáng chú ý đến hai điều.

Đầu tiên, cột thông báo, được chỉ định bằng chú thích @Column(name = "message") , nằm trong bảng phụ trợ user_message, không phải bảng người dùng.

Thứ hai, trong chú thích @JoinColumn(name = "user_id") , chúng tôi đã chỉ định tên của cột user_id, dùng để chỉ id của bảng người dùng. Điều này là để Hibernate biết cách kết hợp chúng một cách chính xác.

Bộ sưu tập

Nếu bạn muốn lưu trữ các phần tử đã sắp xếp của một danh sách hoặc mảng trong một bảng phụ, thì bạn cần một bảng có ba cột:

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

Nếu bạn không thích tên cột "chỉ mục" hoặc bạn không thể thay đổi nó, bạn có thể chỉ định một tên khác trong quá trình ánh xạ. Để làm điều này, bạn cần sử dụng chú thích @Index .

Ví dụ:

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

bộ sưu tập bản đồ

Và cuối cùng, bạn muốn lưu trữ không chỉ một bộ sưu tập mà còn cả HashMap và bạn cần hai cột trong một bảng phụ trợ cho nó:

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

Để chỉ định khóa cho Bản đồ, bạn cần chú thích @MapKeyColumn .

Ví dụ:

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

Bạn có thể tìm thêm thông tin trong tài liệu chính thức .