コレクション一覧

さて、単純な型をマッピングする方法を見てきました。ここで、オブジェクトのコレクションをマッピングする方法という、より興味深い質問に移ります。

そして、オブジェクトを 5 つのグループに分けることができます。

  • 配列- オブジェクトの配列
  • リスト- オブジェクトのリスト
  • セット- オブジェクトのセット
  • マップ- オブジェクトの辞書
  • コレクション- オブジェクトのコレクション

コレクション フィールドを持つクラスの例:

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

   @magical-annotation
   public List messages;
}

では、1 つのフィールドではなく多くの値を保存できるようにするこの魔法のアノテーションとは何でしょうか?

このアノテーションは@ElementCollectionと呼ばれます。例:

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

   @ElementCollection
   public List<String> messages;
}

非常に簡単に書かれていますが、機能は簡単ではありません。

補助テーブル

多くの要素を含み、 @ElementCollectionアノテーションが付いている Entity クラスのすべてのフィールドは、データベース内の特別な補助テーブルに含まれます。実際、これは論理的です。

このテーブルには、次の 2 つの形式のデータを含めることができます。

  • 順序付き(リスト、マップ) には 3 つの列が含まれます。
    • キー列(外部キー) – 親オブジェクトの ID への参照。
    • インデックス列- コレクション内の位置/インデックス。
    • 要素列- 値。
  • 順序なし(セット) には 2 つの列が含まれます。
    • キー列(外部キー) – 親オブジェクトの 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 に任せるのではなく、自分で作成しましょう。まず、2 つの列を持つテーブルを作成する必要があります。

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

このテーブルには独自の id 列がないことに注意してください。これが補助テーブルの最大の特徴です。他のタイプの補助テーブルについては、後ほど説明します。

次に、このテーブルをフィールドにマップする必要がありますメッセージUserクラス内。これは次のようになります。

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

ここで 2 つのことに注意する必要があります。

まず、 @Column(name = "message")アノテーションで指定されたメッセージ列は、user テーブルではなく user_message 補助テーブル内にあります。

次に、@JoinColumn(name = "user_id")アノテーションで、ユーザー テーブルの ID を参照する user_id 列の名前を指定しました。これは、Hibernate がそれらを正しく組み合わせる方法を認識するためです。

コレクション

リストまたは配列の順序付けされた要素を補助テーブルに格納する場合は、次の 3 つの列を持つテーブルが必要です。

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

列名「index」が気に入らない場合、または変更できない場合は、マッピング中に別の名前を指定できます。これを行うには、 @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 も保存したいので、そのための補助テーブルに 2 つの列が必要です。

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

詳細については、公式ドキュメントを参照してください。