Kuina-Dao 開発記 概要
Kuina-Dao を開発中の今日この頃です.
Kuina-Dao というのは,S2Dao や S2Hibernate.Dao の Java Persistence API (JPA) 版です.
いずれは Kuina-Core という独自の JPA 実装を提供する構想もあるわけですが,その前に Hibernate や TopLink など,既存の JPA 実装上で利用できる,S2Dao のように使い勝手のいい DAO フレームワーク (っていうの?) を提供しようというのが Kuina-Dao です.
ようやく SVN へコミットを始めたので,そろそろこちらでも紹介していきます.
今のところ,ダウンロードできる形での配布は準備できていません.
興味を持って頂けた場合は,SVN からチェックアウトしてお試しください.
前提として以下のプロダクトが必要です.
- S2Hibernate-JPA
https://www.seasar.org/svn/s2hibernate
のtrunk/s2hibernate-jpa
- S2Tiger
https://www.seasar.org/svn/s2container
のtrunk/s2-tiger
- Seasar2
https://www.seasar.org/svn/s2container
のtrunk/seasar2
いずれもトランクの最新版をお使いください.
そして
- Kuina-Dao
https://www.seasar.org/svn/kuina
のtrunk/kuina-dao
をチェックアウトしてください.
なお,Kuina は JPA を使うために Java5 必須です.J2SE1.4 ではビルドできません.
例によってソースにコメント無し,ドキュメントも無し,テストケースは貧弱です (苦笑).
さて.
Kuina-Dao は S2Dao や S2Hibernate.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 は事前に問い合わせがきっちり決まっている場合に有用ですが,問い合わせ条件が可変になる場合には使えません.
そんなわけで (どんなわけで?),S2Dao や S2Hibernate.Dao 同様に,問い合わせの自動生成をサポートします.
例えば
List<Employee> find(String name, String email, String bloodType);
というメソッドの場合,実引数が null
でない項目だけを WHERE 句に加えた JPQL を作成し実行します.
JPA では Criteria が使えないため,動的に問い合わせ条件を変えるのは (難しくはないけど) 面倒なわけで,重宝するのではないかと.
最初は SELECT 文のサポートから始めますが,いずれは UPDATE・DELETE (Bulk Operation) もサポートするとか.
S2Dao の SQL コメントのように,JPQL に制御コメントを埋め込めるようにするとか.
S2Dao 同等の Native Query (SQL) もサポートするとか.
といったことを考えています.
要望などあれば,コメント・トラックバック・ML・某巨大掲示板 (笑) など,お好きなところでリクエストください.
よろしくお願いしますです〜.