컬렉션 목록

지금까지 간단한 유형을 매핑하는 방법을 살펴보았습니다. 이제 좀 더 흥미로운 질문인 개체 컬렉션을 매핑하는 방법으로 넘어갈 시간입니다.

그리고 객체를 5개 그룹으로 가질 수 있습니다.

  • 배열 - 객체의 배열
  • 목록 - 개체 목록
  • 세트 - 객체 세트
  • 지도 - 객체 사전
  • 컬렉션 - 객체의 컬렉션

컬렉션 필드가 있는 클래스의 예:

@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 주석 으로 표시된 Entity 클래스의 모든 필드는 특수 보조 테이블의 데이터베이스에 포함됩니다. 사실 논리적입니다.

이 테이블에는 두 가지 형식의 데이터가 포함될 수 있습니다.

  • Ordered (List, Map)에는 세 개의 열이 있습니다.
    • 키 열 (외래 키) – 상위 개체의 ID에 대한 참조입니다.
    • 인덱스 열 - 컬렉션의 위치/인덱스입니다.
    • 요소 열 - 값.
  • 정렬되지 않음 (세트)에는 두 개의 열이 있습니다.
    • 키 열 (외래 키) – 상위 개체의 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 클래스 및 필드 이름)을 기반으로 테이블 이름 자체를 빌드합니다.메시지테이블 이름을 "User_messages"로 지정합니다.

컬렉션 컬렉션

그러나 보조 테이블의 생성을 Hibernate에 맡기지 말고 직접 생성하도록 합시다. 먼저 두 개의 열이 있는 테이블을 만들어야 합니다.

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

이 테이블에는 고유한 id-column이 없습니다. 이것이 보조 테이블의 주요 기능입니다. 나중에 다른 유형의 보조 테이블에 대해 알게 될 것입니다.

이제 이 테이블을 필드에 매핑해야 합니다.메시지사용자 클래스 에서 . 이것은 다음과 같이 보일 것입니다:

@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 테이블이 아니라 user_message 보조 테이블에 있습니다.

둘째, @JoinColumn(name = "user_id") 주석에서 사용자 테이블의 id를 참조하는 user_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)
};

Map의 키를 지정하려면 @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;
}

자세한 내용은 공식 문서에서 확인할 수 있습니다 .