Annotation Processing APIを使った新しいDaoフレームワーク
自分がこれまで関わってきたS2Dao、S2JDBC、Kuina-Daoを踏まえて、Annotation Processing APIを利用した新しいDaoフレームワークを作ってみることにしました。ちょっとアイデアをさらしてみる。
特徴は、次の3つです。
ちょっと例を見てください。
ユーザーが作成するのは1つのテーブルにつきEntityクラスとDaoクラスの2つだけです。
Entityクラス
@Entity public interface Employee { @Id IntegerDomain id(); StringDomain name(); Salary salary(); }
Daoクラス
@Dao public interface EmployeeDao implements GenericDao<Employee> { @Select(file="selectByName.sql") Employee selectByName(StringDomain name); }
Annotation Processing APIで、実装クラス、実装クラスを取得するファクトリクラス、メタ情報を管理するクラスが作成されます。S2DaoなどでAOPを使って実行時に行っていることをコンパイル時にやってしまう感じです。
そして使用例はこんな感じ。例の中のEmployeeFactoryやEmployeeDaoFactoryは自動生成されるクラスです。自動生成された実装クラスをインスタンス化し、利用者側にインタフェースの型で返します。
検索
StringDomain name = new StringDomain("aaa"); EmployeeDao dao = EmployeeDaoFactory.newInstance(); Employee emp = dao.selectByName(name); Salary salary = emp.salary();
追加
Employee emp = EmployeeFactory.newInstance(); emp.id().set(1); emp.name().set("hoge"); EmployeeDao dao = EmployeeDaoFactory.newInstance(); dao.insert(emp);
Entityはインタフェースです。ActiveObjectsとかもそうですね。でもActiveObjectsと違うのは、getter/setterを書くわけではなく、メソッドでプロパティを表します。そして、その戻り値の型はDomainというインタフェースの実装クラスで表現するというのが、また特徴的です。StringとかIntegerといった基本的な型に対応するXxxDomainはフレームワークで提供しますが、Salaryみたいなアプリ用のカスタムDomainを作れます。カスタムのDomainは基本的なDomainを継承したり委譲したりしてつくります。カスタムDomainのいいところはロジックを持たせられることです。これはエンティティ自体にロジックがあるよりも便利なんじゃないでしょうか。特定のエンティティに紐づいているわけではないので、必要なところで使用しそのロジックを呼び出せます。
DaoについてはS2Daoの規約をアノテーションで明示するような形になります。検索はSQLファイルに記述されたSQLを実行する機能だけをサポートします。更新は基本自動で実行し、アノテーションでSQLファイルの実行ができるようにします。SQLファイルの存在チェックは、Annotation Processing APIで行うので、動かしてみたらSQLファイルがなかったということがなくなります。また、パラメータ名はAnnotation Processing APIで取れるので、だれもが一度ははまる?Argumentsアノテーションに相当するものは不要です。
あと、上の例では、ジェネリックなDaoを使って更新系メソッドなど、どのDaoにも共通のメソッドはもたなくていいようにしています。
と、こんな感じでGW中に基本的な機能が動くところまでもっていきたいなぁと思っています。