S2JDBC のタイプセーフ API がすごい

今のプロジェクトでDBアクセスには S2JDBC を使っています。
S2JDBC-genをフルに使って、開発をしたかったのですがS2JDBC-genはエンティティなどのコードの自動生成の機能のみ使用しています。


自動生成の対象は entity, names, service, condition あと entity, service のテストクラスです。

タイプセーフ API を試してみる

企業マスタ(company)から指定した企業マスタID(1)のレコードを取得する場合
import static jp.co.suusuke.entity.CompanyNames.*;
import static org.seasar.extension.jdbc.operation.Operations.*;

...

Company company =
	jdbcManager
        	.from(Company.class)
                .where(eq(companyId(), 1))
                .getSingleResult();

Operations.eq() を使うことでパラメータの companyId() と 1 の 型が同じかどうかコンパイル時にチェックできるようになってます。(companyId()の戻り値がPropertyNameのため)

企業マスタ(company)と社員マスタ(employee)を結合して指定した社員マスタID(1),有効日付(20081228)のレコードを取得する場合

企業マスタと社員マスタは 1:N の関係でエンティティは以下のような感じで関連するエンティティを書く。

Company.java

     @OneToMany(mappedBy = "company")
     public List<Employee> employeeList;

Employee.java

     @ManyToOne
     @JoinColumn(name = "COMPANY_ID")
     public Company company;

名前クラスに以下のようなプロパティを追加する。
静的ネストクラス(_CompanyNames extends PropertyNames)によって、関連するエンティティの名前クラスもタイプセーフにコーディングする事ができる。(ネストは何段階でも無制限に指定可能)


EmployeeNames.java

     /**
      * companyのプロパティ名を返します。
      * 
      * @return companyのプロパティ名
      */
     public static _CompanyNames company() {
         return new _CompanyNames("company");
     }
	

     /**
      * @author S2JDBC-Gen
      */
     public static class _EmployeeNames extends PropertyName<Employee> {

	...


         /**
          * companyのプロパティ名を返します。
          * 
          * @return companyのプロパティ名
          */
         public _CompanyNames company() {
             return new _CompanyNames(this, "company");
         }


     }	


CompanyNames.java

     /**
      * @author S2JDBC-Gen
      */
     public static class _CompanyNames extends PropertyName<Company> {

        ...

     }
import static jp.co.suusuke.entity.EmployeeNames.*;
import static org.seasar.extension.jdbc.operation.Operations.*;

...

Date today = new Date();

Employee employee =
	jdbcManager
        	.from(Employee.class)
                .innerJoin(company())
                .where(
                     eq(employeeId(), 1),
                     le(company().validStartDay(), today),
                     ge(company().validEndDay(), today))
		 .getSingleResult();


innerJoinのパラメータやeq,le等のパラメータは CharSequence または CharSequence を継承したクラスになっていて 名前クラスのプロパティはそれぞれ、 CharSequence を継承した PropertyName を戻り値で返す仕組みにすることで、タイプセーフなコーディングを実現している。

ネストした(関連のエンティティ)まで対応出来るのがすげー。

いやー、S2JDBC + S2JDBC-genはすげー。