Doma 0.9.6 のクールなところ

ちょっと細かいところをいくつかアピールしてみます。

SQLファイル中のコメント式のaptを使った検証がかしこくなりました。

Daoのメソッドがこんなだとします。

@Select
List<Employee> selectByExample(Employee e);

対応するSQLがこんなだとします。

select * from EMPLOYEE where 
/*%if e.employeeName.startsWith(123)*/
    EMPLOYEE_NAME >= /* e.employeeName */'aaa'
/*%end*/

ifのコメントのなかでstartsWithメソッドを呼んでいるのですが(employeeNameはString型)、パラメータの型が数値型になってしまっています。これは間違いなのですが、このとき、こんなメッセージが(実行時ではなくコンパイル時に)出ます。

[DOMA4092] SQLファイル[META-INF/org/seasar/doma/it/dao/EmployeeDao/selectByExample.sql]の妥当検査に
 失敗しました。SQL[select * from EMPLOYEE where /*%if e.employeeName.startsWith(123)*/ EMPLOYEE_NAME 
 >= /* e.employeeName */'aaa' /*%end*/ ]([2]行目[38]番目の文字付近)。詳細は次のものです。[DOMA4071] 式
 [ e.employeeName.startsWith(123)]([26]番目の文字付近)に含まれる変数[.employeeName](フィールドもしくはメソッドの
 戻り値の型が[java.lang.String])からpublicで戻り値を返すメソッド[startsWith(int)]が見つかりません。

最後のところを見てほしいのですが、そんなメソッドみつかりませんということで、ちゃんと型チェックをしているのがわかります。オーバーロード、オーバーライドがあっても適切なメソッドを探せます。また、これまではメソッド呼び出ししかできなかったのですが、フィールドアクセスも可能になりました。

ほかにも論理演算子の被演算子がboolean/Boolean型に評価できなかったらエラーにするとか結構細かく解析するようになっています。

publicフィールドなエンティティクラスが可能です。

@Entity
public class Employee {
  @Id
  public Integer id;
  public String name;
}

もちろん、publicをとってgetter/setterつけてもOKです。どっちを使うかはプロジェクトやアプリの特性で選べばいいと思います。
(ただし、Domaはリフレクションなしでフィールドアクセスするのでフィールドをprivateにはできません。フィールドを公開したくないのであればパッケージプライベートを使ってください。)

条件用オブジェクトは好きなだけ指定できます。

S2Daoだと検索条件用オブジェクト(DTO)をつくったら1つしかパラメータで渡せませんが、Domaでは何個でも渡せます。

@Select
select(Employee e, Department d, Address a、String aaa);

少しはDTO爆発を抑えられるかも。

ストアドプロシージャー/ファンクションを強力にサポートしています。

S2DaoS2JDBCとちがうのは、パラメータをDTOにつめて渡すのではなくフラットで渡すこと。
カーソルも扱えます(@ResultSetをつける)。INOUTパラメータやOUTパラメータはReferenceクラスというものをつかってやりとりします。

@Procedure
void exec(@ResultSet List<Employee> employees,
        @In Integer employee_id, @Out Reference<Integer> count);

使用例

List<Employee> employees = new ArrayList();
Reference<Integer> countRef = new Reference<Integer>();
EmployeeDao dao = new EmployeeDaoImpl();
dao.exec(employees, 10, countRef );

assertTrue(employees.size() > 0);

Integer count = countRef.get();
assertNotNull(count);

リフレクションほとんどつかっていません。

SQLファイルの条件式コメントやバインド変数コメントを扱うところ以外ではリフレクションを使っていません。
エンティティのインスタンス化やプロパティアクセス等、通常のフレームワークではリフレクションを使用するであろうところで使っていないということです。そのため、リフレクションの情報をキャッシュするとかもしなくてすんでいます。

まだちゃんと計っていないですけど、S2Daoとかよりは動作が軽いと思います。


というわけで、ぜひ使ってみてください。
http://doma.sandbox.seasar.org/downloads.html