minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

よく、DBテーブルは2つ以上のテーブルをJoinして使われます。
もちろんこれはパフォーマンスの面から言えばよくない事なのですが
保守性を高める意味では非常に有効な手段となります。
プログラムと同じように、DBにも同じレコードを複数格納するのは
避けた方が良いのです。

1対1対応

Entity Bean "Person" と Entity Bean "Address" を結び付けてみます。
それぞれが持つフィールドは以下のようにします。

"Person"

id

プライマリ・キー

name

名前

address

住所

"Address"

id

プライマリ・キー

zipCode

郵便番号

city

街名

基本的な実装方法は Entity Bean のページを見てもらうことにして、
ここでは結び付けに関する事だけを記述します。

@Entity
public Person implements Serializable {

    public Person(...) {
      Address aAddress = new Address();
      aAddress.setZipCode(...);
      setAddress(address);
    }

    @Id(generate = GeneratorType.AUTO)
    public int getId() { ... }
    ...

    @OneToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "addressId")
    public Address getAddress() { return address; }
    private Address address;
    ...

}

@Entity
public Address implements Serializable {

    @Id(generate = GeneratorType.AUTO)
    public int getId() { ... }
    ...
}

Personの定義に (({@OneToOne}}} Annotationを記述します。
Addressの方は通常のEntity Beanと全く同じです。
つまり、Addressは単独でも使うことが出来ます。

今回は簡易の為、Personと結び付けるAddressをコンストラクタ内で作成しています。

@OneToOne

文字通り、Entity Bean同士を1対1で結び付けます。

cascade

詳しい事は不明です。
とりあえず、このように記述しておけばいいようです。

@OneToOne(cascade = {CascadeType.ALL})

@JoinColumn

結び付けるためのカラムを定義します。
このカラムは、Personテーブル上に実装されることになります。

実装内容

上の定義により、PersonとAddressは1対1対応となります。
実際のテーブル定義は、例えば以下のようになります。

CREATE TABLE Person (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(255),
  addressId INTEGER
);
CREATE TABLE Address (
  id INTEGER AUTO_INCREMENT PRIMARY KEY,
  zipCode VARCHAR(255),
  city VARCHAR(255)
);

テーブルPersonに「addressId」というカラムが定義されています。
これがAddressテーブルのidとリンクしています。