About

ドキュメント

プロジェクト文書

Built by Maven

概要

SQLファイルは、SQL文を格納したテキストファイルで、Daoのメソッドにマッピングされます。 SQLのブロックコメント(/* */)や行コメント(--)を使用することで、バインド変数や動的なSQLのための条件分岐を表現できます。 SQLのツールでそのままそのSQLを実行できるように、バインド変数にはテスト用のデータを指定します。テスト用のデータは、実行時には使用されません。 たとえば、SQLファイルには次のようなSQL文が格納されます。

select * from employee where employee_id = /*employeeId*/99

ここでは、ブロックコメントで囲まれた employeeIdがDaoインタフェースのメソッドのパラメータに対応し、 直後の 99はテスト用の条件になります。 対応するDaoインタフェースのメソッドは次のとおりです。

Employee selectById(employeeId);

SQLファイルにマッピングするためのアノテーション

SQLファイルとDaoのメソッドのマッピングは次のアノテーションで示します。

  • @Select
  • @Insert(sqlFile = true)
  • @Update(sqlFile = true)
  • @Delete(sqlFile = true)
  • @BatchInsert(sqlFile = true)
  • @BatchUpdate(sqlFile = true)
  • @BatchDelete(sqlFile = true)

SQLファイル

配置場所

SQLファイルはクラスパスが通った META-INF ディレクトリ以下に配置しなければいけません。

ファイル名の形式

ファイル名は、次の形式でなければいけません。

META-INF/Dalのクラスの完全修飾名をディレクトリに変換したもの/Data Access Objectのメソッド名.sql

例えば、 Daoのクラスが aaa.bbb.EmployeeDaoで マッピングしたいメソッドが selectById の場合、パス名は次のようになります。

META-INF/aaa/bbb/EmployeeDao/selectById.sql

複数のRDBMSに対応する必要があり特定のRDBMSでは別のSQLファイルを使いたい場合、 .sql の前にハイフン区切りでRDBMS名を入れることで、優先的に使用するファイルを指示できます。 たとえば、PostgreSQL専用のSQLファイルは次の名前にします。

META-INF/aaa/bbb/EmployeeDao/selectById-postgres.sql

この場合、PostgreSQLを使用している場合に限り、META-INF/aaa/bbb/EmployeeDao/selectById.sql よりも META-INF/aaa/bbb/EmployeeDao/selectById-postgres.sql が優先的に使用されます。

RDBMS名は、 org.seasar.doma.jdbc.dialect.DialectgetNameメソッドの値が使用されます。

エンコーディング

SQLファイルのエンコーディングはUTF-8でなければいけません。

SQLコメント

バインド変数コメント

バインド変数は/*~*/というブロックコメントで囲んで示します。バインド変数の名前はDaoインタフェースのメソッドのパラメータ名にマッピングされます。 ブロックコメント直後にはテスト用データを指定する必要があります。テスト用データは、実行時には使用されません。

単一のパラメータ

Daoインタフェースのメソッドのパラメータが基本型もしくはドメインクラスの場合について説明します。 単一のパラメータは、1つのバインド変数コメントに対応します。 Daoインタフェースのメソッドと、対応するSQLの例は次のとおりです。

List<Employee> selectById(Integer employeeId);
select * from employee where employee_id = /*employeeId*/99

/*employeeId*/は、/* employeeId */のように空白を含めて記述することも可能です。

Listのパラメータ

Daoインタフェースのメソッドのパラメータが基本型もしくはドメインクラスを要素とするjava.util.Listの場合について説明します。 Listのパラメータは、IN句の1つのバインド変数コメントに対応しますが、複数の値をバインドできます。 ブロックコメントはINキーワードの直後に置き、ブロックコメントの直後には括弧つきでテスト用データを指定します。テスト用データは、実行時には使用されません。 Daoインタフェースのメソッドと、対応するSQLの例は次のとおりです。

List<Employee> selectByIdList(List<Integer> employeeIdList);
select * from employee where employee_id in /*employeeIdList*/(1,2,3)

/*employeeIdList*/は、/* employeeIdList */のように空白を含めて記述することも可能です。

エンティティクラスのパラメータ

Daoインタフェースのメソッドのパラメータがエンティティクラスの場合について説明します。 エンティティクラスのパラメータは、複数のバインド変数コメントに対応します。 ブロックコメントの中では、ドット(.)を使用しエンティティのフィールドにアクセスできます。 Daoインタフェースのメソッドと、対応するSQLの例は次のとおりです。

List<Employee> selectByNameAndSalary(Employee employee);
select * from employee
where
employee_name = /*employee.employeeName*/'abc' 
and
salary = /*employee.salary*/1234

/*employee.employeeName*/は、/* employee.employeeName */のように空白を含めて記述することも可能です。

フィールドにアクセスする代わりに、publicなメソッドを呼び出すことも可能です。

select * from employee
where
salary = /*employee.getTaxedSalary()*/1234

埋め込み変数コメント

埋め込み変数は/*#~*/というブロックコメントで示します。埋め込み変数の名前はメソッドのパラメータ名にマッピングされます。 埋め込み変数はORDER BY句など、SQLの一部をプログラムで組み立てたい場合に使用できます。 安全のため、埋め込み変数の一部にシングルクォテーション、セミコロン、ラインコメント、ブロックコメントを含めることは認められていません。 シングルクォテーション以外のSQLインジェクション対策はアプリケーションの責任になります。 Daoのメソッドと、対応するSQLの例は次のとおりです。

List<Employee> selectAll(BigDecimal salary, String orderyBy);
select * from employee where salary > /*salary*/100 /*#orderBy*/

Daoの呼び出し例は次の通りです。

EmployeeDao dao = new EmployeeDaoImpl();
BigDecimal salary = new BigDecimal(1000);
String orderBy = "order by salary asc, employee_name";
List<Employee> list = dao.selectAll(salary, orderBy);

発行されるSQLは次のようになります。

select * from employee where salary > ? order by salary asc, employee_name

/*#orderBy*/は、/*# orderBy */のように空白を含めて記述することも可能です。

条件コメント

ifend

条件によってSQLを組み立てる場合は、/*%if 条件*/ ~ /*%end*/という構文を使用できます。

select * from employee where /*%if employeeId != null*/employee_id = /*employeeId*/99/*%end*/

このSQL文は、 employeeIdnullでない場合 次のような準備された文に変換されます。

select * from employee where employee_id = ?

このSQL文は、 employeeIdnullの場合に次のような準備された文に変換されます。

select * from employee

WHEREHAVINGの自動除去

条件コメントを使用した場合、条件の前にあるWHEREやHAVINGについて、自動で出力の要/不要を判定します。 たとえば、次のようなSQLでemployeeIdnullの場合、

select * from employee where 
/*%if employeeId != null*/
    employee_id = /*employeeId*/99
/*%end*/

/*%if*/の前の whereは自動で除去されます。

select * from employee

ANDORの自動除去

条件コメントを使用した場合、条件の後ろにつづくANDやORについて、自動で出力の要/不要を判定します。 たとえば、次のようなSQLでemployeeIdnullの場合、

select * from employee where 
/*%if employeeId != null*/
    employee_id = /*employeeId*/99
/*%end*/
and employeeName like 's%'

/*%end*/の後ろの and は自動で除去されます。

select * from employee where employeeName like 's%'

elseifelse

/*%if 条件*//*%end*/ の間では、 行コメントを使用した --elseif 条件----else という構文も使用できます。

select * from employee where 
/*%if employeeId != null*/   employee_id = /*employeeId*/99
--elseif employeeId == 999-- department_id is null
--else                       employee_id is null
/*%end*/

ネストした条件コメント

条件コメントはネストさせることができます。

select * from employee where 
/*%if employeeId != null*/
  employee_id = /*employeeId*/99
  /*%if employeeName != null*/ 
    and employee_name = /*employeeName*/'hoge'
  /*%end*/
/*%end*/

通常のブロックコメント

/*の直後に、空白以外のJavaの変数で使用できない値が続く場合、それは通常のSQLコメントだとみなされます。 ただし、条件コメントを示す %や 埋め込みコメントを示す#がつづく場合は通常のコメントとみなされません。

たとえば、次の例は通常のブロックコメントとみなされます。

/** aaa */
/*+aaa */

次の例は通常のブロックコメントとみなされません。

/* id */
/*$aaa*/
/*%aaa*/
/*#aaa*/

/* id */は空白が除去されidというバインド変数とみなされます。 /*$aaa*/$aaaというバインド変数とみなされます。 /*%aaa*/%で始まっているため条件コメントとして解釈されます(しかし、ifでもendでもないためエラーとなります)。 /*#aaa*/aaaという埋め込み変数コメントとみなされます。

通常の行コメント

--の直後に、elseifelseがつづかない場合、それは通常のSQLコメントだとみなされます。

たとえば、次の例は通常の行コメントだとみなされます。

-- aaa

式言語

条件コメントの /*%if 条件*/ や、 --elseif 条件-- の条件部には、式を記述できます。

定数

次の定数が用意されています。

定数
null void
true boolean
false boolean
10 int
10L long
0.123F float
0.123D double
0.123B java.math.BigDecimal
'a' char
"a" String

比較演算子

以下の比較演算子を使用できます。

比較演算子
==
!=
<
<=
>
>=

比較演算子を利用するには、 被演算子が java.lang.Comparableを実装している必要があります。

<<=>>=では、 非演算子にnullリテラルを使用できません。

論理演算子

以下の論理演算子を使用できます。

論理演算子
!
&&
||

括弧を使って、演算子が適用される優先度を制御できます。

select * from employee where 
/*%if (departmentId == null || managerId == null) and employee_name != null*/
    employee_name = /*employeeName*/'smith'
/*%end*/

算術演算子

以下の算術演算子を使用できます。

算術演算子
+
-
*
/

被演算子は数値型でなければいけません。

メソッド呼び出し

ドット(.)で区切ってメソッド名を指定することでメソッドを実行可能です。実行可能なメソッドは、可視性がpublicなものだけに限られます。

select * from employee where 
/*%if employeeName.startsWith("s") */
    employee_name = /*employeeName*/'smith'
/*%end*/

引数がない場合は、メソッド名の後ろに()を指定します。

select * from employee where 
/*%if employeeName.length() > 10 */ 
    employee_name = /*employeeName*/'smith'
/*%end*/

フィールドアクセス

ドット(.)で区切ってフィールド名を指定することでフィールドにアクセスできます。アクセス可能なフィールドはインスタンスフィールドです。 可視性はprivateであってもアクセス可能です。

select * from employee where 
    employee_name = /*employee.employeeName*/'smith'