Kuina-Dao 開発記 概要

Kuina-Dao を開発中の今日この頃です.
Kuina-Dao というのは,S2DaoS2Hibernate.Dao の Java Persistence API (JPA) 版です.
いずれは Kuina-Core という独自の JPA 実装を提供する構想もあるわけですが,その前に HibernateTopLink など,既存の JPA 実装上で利用できる,S2Dao のように使い勝手のいい DAO フレームワーク (っていうの?) を提供しようというのが Kuina-Dao です.
ようやく SVN へコミットを始めたので,そろそろこちらでも紹介していきます.


今のところ,ダウンロードできる形での配布は準備できていません.
興味を持って頂けた場合は,SVN からチェックアウトしてお試しください.
前提として以下のプロダクトが必要です.

S2Hibernate-JPA
https://www.seasar.org/svn/s2hibernatetrunk/s2hibernate-jpa
S2Tiger
https://www.seasar.org/svn/s2containertrunk/s2-tiger
Seasar2
https://www.seasar.org/svn/s2containertrunk/seasar2

いずれもトランクの最新版をお使いください.
そして

Kuina-Dao
https://www.seasar.org/svn/kuinatrunk/kuina-dao

をチェックアウトしてください.
なお,KuinaJPA を使うために Java5 必須です.J2SE1.4 ではビルドできません.
例によってソースにコメント無し,ドキュメントも無し,テストケースは貧弱です (苦笑).


さて.
Kuina-Dao は S2DaoS2Hibernate.Dao と同様にインターセプタを提供します.
それが

  • org.seasar.kuina.dao.interceptor.KuinaDaoInterceptor

です.
こいつを DAO のインタフェースに適用することで,JPA というか javax.persistence.EntityManager を直接呼び出さなくてもエンティティクラスを操作できる,というのが Kuina-Dao です.
現時点では問い合わせ以外の基本的な操作のみが実装されています.
例えばこんな DAO を用意して...

public interface EmployeeDao {
    Employee find(int id);
    Employee get(int id);
    void persist(Employee employee);
    void remove(Employee employee);
    boolean contains(Employee employee);
    Employee merge(Employee employee);
    void refresh(Employee employee);
    void readLock(Employee employee);
    void writeLock(Employee employee);
}

これに KuinaDaoInterceptor を適用することで,EntityManager に対する基本的な操作を行うことができます.
それぞれのメソッドが EntityManager のどのメソッドに対応するかはすぐにお分かりかと.
これだけだと,わざわざ DAO を用意しなくても EntityManager を使えばいいような気のせいもすることでしょう.
当然ですよね.
そんなわけで (どんなわけで?),これから問い合わせを中心に機能を充実させていきます.


最初はたぶん,Named Query のサポート.
JPA では @NamedQuery を使って Java Persitence query language (JPQL) による問い合わせ文字列を登録しておくことができます.

@NamedQuery(name="Employee.findByName",
    query="SELECT e FROM Employee e WHERE e.name = :name")

通常はこれを

public class EmployeeDao {
    List<Employee> findByName(String name) {
        return em.createNamedQuery("Employee.findByName").setParameter("name", name).getResultList();
    }
}

みたいに使うのですが,これを

public interface EmployeeDao {
    List<Employee> findByName(String name);
}

というインタフェースを用意するだけで済むようにします.
この際,Named Query の名前はメソッドの戻り値から得られるエンティティ名とメソッド名から,パラメータ名は引数名から解決します.
一応,アノテーションで Named Query の名前を指定できるようにするつもり.
それから,引数名を取れない環境のために,Named Parameter (:name と書く方法) に加えて Positional Parameter (?1 と書く方法) もサポートするつもり.


Named Query は事前に問い合わせがきっちり決まっている場合に有用ですが,問い合わせ条件が可変になる場合には使えません.
そんなわけで (どんなわけで?),S2DaoS2Hibernate.Dao 同様に,問い合わせの自動生成をサポートします.
例えば

    List<Employee> find(String name, String email, String bloodType);

というメソッドの場合,実引数が null でない項目だけを WHERE 句に加えた JPQL を作成し実行します.
JPA では Criteria が使えないため,動的に問い合わせ条件を変えるのは (難しくはないけど) 面倒なわけで,重宝するのではないかと.


最初は SELECT 文のサポートから始めますが,いずれは UPDATE・DELETE (Bulk Operation) もサポートするとか.
S2DaoSQL コメントのように,JPQL に制御コメントを埋め込めるようにするとか.
S2Dao 同等の Native Query (SQL) もサポートするとか.
といったことを考えています.


要望などあれば,コメント・トラックバック・ML・某巨大掲示板 (笑) など,お好きなところでリクエストください.
よろしくお願いしますです〜.