N:1のSELECT

これまでで、BOOKテーブルに関する基本的なCRUDはできた。と振り返ってみるともう2週間も前のことなのか、、、怠けてるな自分。。。
さて、S2Daoの機能はまだまだあるわけで、ここで終わってはいかん。というわけで、この辺で新しいテーブルを登場させてBOOKテーブルと結合した結果を取得できるようにしてみることにしようと思う(こういう発展を最初から想定していたわけではないから、だんだん苦しくなってくるんだろうなぁ…)。
書籍は出版社がないと世には出回らないはずなので、出版社の情報を持つPUBLISHERテーブルを導入してみる。テーブルは次のとおり。

CREATE SEQUENCE SEQ_PUBLISHER_ID AS NUMERIC(4);
CREATE TABLE PUBLISHER (
       id NUMERIC(4) NOT NULL IDENTITY PRIMARY KEY
     , name VARCHAR(50) NOT NULL
);

1冊の書籍に対して出版社は1社で、1社の出版社に対して書籍は複数冊あるので、ここではBOOKテーブルが出版社の情報を持つようにする。BOOKテーブルにPUBLISHERテーブルのidを持つpublisher_idを追加する。

CREATE TABLE BOOK (
       id NUMERIC(5) NOT NULL IDENTITY PRIMARY KEY
     , name VARCHAR(50) NOT NULL
     , publisher_id NUMERIC(4) NOT NULL
     , CONSTRAINT FK_BOOK_PUBLISHER FOREIGN KEY (publisher_id)
                  REFERENCES PUBLISHER (id)
);

この関係をBOOKテーブルからみるとN:1の関係になる。ということで、S2DaoでN:1を実現するRELNOアノテーションとRELKEYSアノテーションを使ったN:1マッピング機能が使える。SQL文は、今回も自動生成に任せる方向なので書かないつもり。

これらのアノテーションを、BOOKテーブルを表すBookクラスに書くとこんな感じになる。

package examples.s2dao.book.entity;

import java.io.Serializable;

public class Book implements Serializable {
    public static final String id_ID="sequence, sequenceName=SEQ_BOOK_ID";
    // N:1の指定
    public static final int publisher_RELNO = 0;
    public static final String publisher_RELKEYS = "publisher_id:id";
    
    private int id;
    private String name;
    private Publisher publisher;
    :
    
    public void setPublisher(Publisher publisher) {
        this.publisher = publisher;
    }
    
    public Publisher getPublisher() {
        return publisher;
    }

RELNOアノテーションで結合のユニークな番号を、RELKEYSアノテーションで結合するカラムを表している。詳細はドキュメントを見るとして、当然のことなのだけど気を付けるのは、RELKEYSアノテーションを適用するプロパティは結合先のテーブルを表すBeanでなくてはいけないということ。ここではPUBLISHERテーブルのBeanであるPublisherクラス(ソースは省略)をプロパティにしている。これで、PUBLISHERテーブルの値がPublisherクラスのオブジェクトに格納されるようになる。
あとは適当なデータを入れて最初に作ったBookClientを実行すれば動くはず...

DEBUG 2005-05-01 22:40:17,008 [main] 物理的なコネクションを取得しました
DEBUG 2005-05-01 22:40:17,008 [main] 論理的なコネクションを取得しました
DEBUG 2005-05-01 22:40:17,459 [main] 論理的なコネクションを閉じました
DEBUG 2005-05-01 22:40:17,519 [main] SELECT Book.name, Book.id, Book.publisher_id, publisher.name AS name_0, publisher.id AS id_0 FROM Book LEFT OUTER JOIN Publisher publisher ON Book.publisher_id = publisher.id WHERE BOOK.id = 0
DEBUG 2005-05-01 22:40:17,519 [main] 論理的なコネクションを取得しました
DEBUG 2005-05-01 22:40:17,559 [main] 論理的なコネクションを閉じました
id: 0, name: Seasar2入門(仮), publisher: id: 0, name: S2自費出版
DEBUG 2005-05-01 22:40:17,559 [main] 物理的なコネクションを閉じました

動いた。LEFT OUTER JOINになっていて取得できてるのがわかる。
RELNOアノテーションで指定した番号が結合先のカラムの別名に付加されている。これで一意にしてるんだね。