<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
	<properties>
		<title>検索</title>
	</properties>
	<body>
		<section name="目次">
			<ul>
				<li><a href="#概要">概要</a></li>
				<li><a href="#単純な検索">単純な検索</a></li>
				<li><a href="#条件分岐を用いた検索">条件分岐を用いた検索</a></li>
				<li><a href="#条件分岐でelseを用いた検索">条件分岐でelseを用いた検索</a></li>
				<li><a href="#繰り返しを用いた検索">繰り返しを用いた検索</a></li>
				<li><a href="#IN述語による検索">IN述語による検索</a></li>
				<li><a href="#LIKE述語による検索">LIKE述語による検索</a>
					<ul>
						<li><a href="#前方一致検索">前方一致検索</a></li>
						<li><a href="#後方一致検索">後方一致検索</a></li>
						<li><a href="#中間一致検索">中間一致検索</a></li>
					</ul>
				</li>
				<li><a href="#日付による範囲検索">日付による範囲検索</a></li>
				<li><a href="#文字シーケンスを組み込み関数で判定する検索">文字シーケンスを組み込み関数で判定する検索</a></li>
				<li><a href="#ドメインによる検索">ドメインによる検索</a></li>
				<li><a href="#エンティティによる検索">エンティティによる検索</a></li>
				<li><a href="#ページングを行う検索">ページングを行う検索</a></li>
				<li><a href="#ページングと集計を同時に行う検索">ページングと集計を同時に行う検索</a></li>
				<li><a href="#イテレーション検索">イテレーション検索</a></li>
				<li><a href="#結合した結果を取得する検索">結合した結果を取得する検索</a></li>
			</ul>
		</section>
		<section name="概要">
			<p>
				検索は、すべて外部化されたSQLを使って行われます。
			</p>
			<p>
				外部化されたSQLはすべてバインド変数（?）を使った準備された文に変換されて実行されますが、
				このドキュメントでは、発行されたSQLがどのようなものかわかりやすくするためにバインド変数を実際の値に置き換えたログ用のSQLを示します。
			</p>
		</section>
		<section name="単純な検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestSimpleSelectメソッドを参照してください。
				引数をSQLファイルにバインディングして実行する単純な検索です。
				バインディングには<a href="../reference/sqlfile.html#バインド変数コメント">バインド変数コメント</a>を使用します。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
			</p>
<source><![CDATA[@Select
Employee selectById(Integer id);]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectById.sqlです。SQLは次のように記述されています。
			</p>
<source><![CDATA[select * from employee where id = /* id */0]]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
			</p>
<source><![CDATA[Employee employee = dao.selectById(1);]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee where id = 1]]></source>
		</section>
		<section name="条件分岐を用いた検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestConditinalSelectメソッドを参照してください。
				SQLファイル中に<a href="../reference/sqlfile.html#条件コメント">条件コメント</a>を記述することで動的なSQLを発行できます。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
			</p>
<source><![CDATA[@Select
List<Employee> selectByAgeRange(Integer min, Integer max);]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectByAgeRange.sqlです。SQLは次のように記述されています。
			</p>
<source><![CDATA[select * from employee
where
/*%if min != null */
  age >= /* min */10
/*%end */
/*%if max != null */
  and
  age <= /* max */70
/*%end */
order by age]]></source>
			<subsection name="条件1">
			<p>
				1番目のパラメータに30、2番目のパラメータに40を渡してDaoのメソッドを呼び出します。
			</p>
<source><![CDATA[List<Employee> list = dao.selectByAgeRange(30, 40);]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee
where
  age >= 30
  and
  age <= 40
order by age]]></source>
			</subsection>
			<subsection name="条件2">
			<p>
				1番目のパラメータに30、2番目のパラメータにnullを渡してDaoのメソッドを呼び出します。
			</p>
<source><![CDATA[list = dao.selectByAgeRange(30, null);]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee
where
  age >= 30
order by age]]></source>
			</subsection>
			<subsection name="条件3">
			<p>
				1番目のパラメータにnull、2番目のパラメータに40を渡してDaoのメソッドを呼び出します。
			</p>
<source><![CDATA[list = dao.selectByAgeRange(null, 40);]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee
where
  age <= 40
order by age]]></source>
			</subsection>
			<subsection name="条件4">
			<p>
				1番目のパラメータにnull、2番目のパラメータにnullを渡してDaoのメソッドを呼び出します。
			</p>
<source><![CDATA[list = dao.selectByAgeRange(null, null);]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee
order by age]]></source>
			</subsection>
		</section>
		<section name="条件分岐でelseを用いた検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestConditinalSelect2メソッドを参照してください。
				SQLファイル中に<a href="../reference/sqlfile.html#条件コメント">条件コメント</a>を記述することで動的なSQLを発行できますが、条件が成り立たない場合を /*%else*/ という式コメントで記述できます。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
			</p>
<source><![CDATA[@Select
List<Employee> selectByName(String name);]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectByName.sqlです。SQLは次のように記述されています。
			</p>
<source><![CDATA[select * from employee
where 
/*%if name != null*/
  name = /*name*/'hoge'
/*%else */
  and
  name is null
/*%end */]]></source>
			<subsection name="条件1">
			<p>
				パラメータに"SMITH"を渡してDaoのメソッドを呼び出します。
				この場合、name != null という条件が成り立ちます。
			</p>
<source><![CDATA[List<Employee> list = dao.selectByName("SMITH");]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee
where 
  name = 'SMITH']]></source>
			</subsection>
			<subsection name="条件2">
			<p>
				パラメータにnullを渡してDaoのメソッドを呼び出します。
				この場合、name != null という条件は成り立ちません。
			</p>
<source><![CDATA[list = dao.selectByName(null);]]></source>
			<p>
				SQLのログは次のように出力されます。where句の直後のandは自動で除去されます。
			</p>
<source><![CDATA[select * from employee
where 
  
  name is null]]></source>
  				<p>
  					elseだけではなくelseifを表すこともできます。
  					詳細は<a href="../reference/sqlfile.html#elseifとelse">elseifとelse</a>を参照してください。
  				</p>
			</subsection>
		</section>
		<section name="繰り返しを用いた検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestLoopSelectメソッドを参照してください。
				SQLファイル中に<a href="../reference/sqlfile.html#繰り返しコメント">繰り返しコメント</a>を記述することで、動的なSQLを発行できます。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
			</p>
<source><![CDATA[@Select
List<Employee> selectByAges(List<Integer> ages);]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectByAges.sqlです。SQLは次のように記述されています。
				次の要素がある場合にのみ表示したい文字列（この例ではor）は、<a href="../reference/sqlfile.html#埋め込み変数コメント">埋め込み変数コメント</a>で表します。
			</p>
<source><![CDATA[select * from employee where 
/*%for age : ages */
  age = /* age */30
  /*%if age_has_next */
  /*# "or" */
  /*%end */
/*%end */]]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
			</p>
<source><![CDATA[List<Integer> ages = Arrays.asList(30, 40, 50, 60);
List<Employee> list = dao.selectByAges(ages);]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee where 
  age = 30
  or
  age = 40
  or
  age = 50
  or
  age = 60;]]></source>
		</section>
		<section name="IN述語による検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestInPredicateメソッドを参照してください。
				IN述語を使った検索です。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
			</p>
<source><![CDATA[@Select
List<Employee> selectByNames(List<String> names);]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectByNames.sqlです。SQLは次のように記述されています。
			</p>
<source><![CDATA[select * from employee where name in /* names */('aaa', 'bbb')']]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
			</p>
<source><![CDATA[List<String> names = Arrays.asList("JONES", "SCOTT", "XXX");
List<Employee> list = dao.selectByNames(names);]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee where name in ('JONES', 'SCOTT', 'XXX')]]></source>
		</section>
		<section name="LIKE述語による検索">
			<subsection name="前方一致検索">
				<p>
					<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestLikePredicate_prefixメソッドを参照してください。
					SQLファイル中で<a href="../reference/sqlfile.html#組み込み関数の使用">組み込み関数</a>「@prefix()」を使用した前方一致検索ができます。
					組み込み関数「@prefix()」を使用するとJavaのコード内で「%」を文字列に連結する処理が不要になります。
				</p>
				<p>
					使用するDaoのメソッド定義は次のとおりです。
				</p>
<source><![CDATA[@Select
List<Employee> selectByNameWithPrefixMatching(String prefix);]]></source>
				<p>
					Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectByNameWithPrefixMatching.sqlです。SQLは次のように記述されています。
				</p>
<source><![CDATA[select * from employee where name like /* @prefix(prefix) */'X%' escape '$']]></source>
				<p>
					Daoのメソッドは次のように呼び出します。
				</p>
<source><![CDATA[List<Employee> list = dao.selectByNameWithPrefixMatching("S");]]></source>
				<p>
					SQLのログは次のように出力されます。
				</p>
<source><![CDATA[select * from employee where name like 'S%' escape '$']]></source>
			</subsection>
			<subsection name="後方一致検索">
				<p>
					<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestLikePredicate_suffixメソッドを参照してください。
					SQLファイル中で組み込み関数「@suffix()」を使用した後方一致検索ができます。
					組み込み関数「@suffix()」を使用するとJavaのコード内で「%」を文字列に連結する処理が不要になります。
				</p>
				<p>
					使用するDaoのメソッド定義は次のとおりです。
				</p>
<source><![CDATA[@Select
List<Employee> selectByNameWithSuffixMatching(String suffix);]]></source>
				<p>
					Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectByNameWithSuffixMatching.sqlです。SQLは次のように記述されています。
				</p>
<source><![CDATA[select * from employee where name like /* @suffix(suffix) */'%X' escape '$']]></source>
				<p>
					Daoのメソッドは次のように呼び出します。
				</p>
<source><![CDATA[List<Employee> list = dao.selectByNameWithSuffixMatching("S");]]></source>
				<p>
					SQLのログは次のように出力されます。
				</p>
<source><![CDATA[select * from employee where name like '%S' escape '$']]></source>
			</subsection>
			<subsection name="中間一致検索">
				<p>
					<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestLikePredicate_insideメソッドを参照してください。
					SQLファイル中で組み込み関数「@contain()」を使用した中間一致検索ができます。
					組み込み関数「@contain()」を使用するとJavaのコード内で「%」を文字列に連結する処理が不要になります。
				</p>
				<p>
					使用するDaoのメソッド定義は次のとおりです。
				</p>
<source><![CDATA[@Select
List<Employee> selectByNameWithInsideMatching(String inside);]]></source>
				<p>
					Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectByNameWithInsideMatching.sqlです。SQLは次のように記述されています。
				</p>
<source><![CDATA[select * from employee where name like /* @contain(inside) */'%X%' escape '$']]></source>
				<p>
					Daoのメソッドは次のように呼び出します。
				</p>
<source><![CDATA[List<Employee> list = dao.selectByNameWithInsideMatching("A");]]></source>
				<p>
					SQLのログは次のように出力されます。
				</p>
<source><![CDATA[select * from employee where name like '%A%' escape '$']]></source>
			</subsection>
		</section>
		<section name="日付による範囲検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestSelectByTimestampRangeメソッドを参照してください。
				日付を用いて範囲検索を行う場合に、日付の時刻部分を切り捨てたり、日付を一日後ろへずらして切りのいい値にしたいことがあります。
				そのような場合には、<a href="../reference/sqlfile.html#組み込み関数の使用">組み込み関数</a>の「@roundDownTimePart()」と「@roundUpTimePart()」を使用します。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
			</p>
<source><![CDATA[@Select
List<Employee> selectByHiredateRange(Timestamp from, Timestamp to);]]></source>
				<p>
					Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectByHiredateRange.sqlです。SQLは次のように記述されています。
				</p>
<source><![CDATA[select * from employee 
where 
  hiredate >= /* @roundDownTimePart(from) */'2001-01-01 12:34:56'
  and 
  hiredate < /* @roundUpTimePart(to) */'2001-01-01 12:34:56']]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
			</p>
<source><![CDATA[Timestamp from = Timestamp.valueOf("2008-01-20 12:34:56");
Timestamp to = Timestamp.valueOf("2008-03-20 12:34:56");
List<Employee> list = dao.selectByHiredateRange(from, to);]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee 
where 
  hiredate >= '2008-01-20 00:00:00.0'
  and 
  hiredate < '2008-03-21 00:00:00.0']]></source>
			<p>
				Javaコードからの引数と比べると時刻部分の切り捨てや切り上げが行われていることがわかります。
			</p>
		</section>
		<section name="文字シーケンスを組み込み関数で判定する検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestIsNotEmptyFunctionメソッドを参照してください。
			</p>
			<p>
				文字シーケンスがnullかどうか、長さが0かどうかといった条件を基に条件分岐したい場合があります。たとえば、「nullでなくかつ長さが0でない場合にのみ検索条件に含める」には、次のようなSQLを記述できます。
			</p>
<source><![CDATA[select * from employee where /*%if name != null && name.length != 0 */ name = /* name */'hoge' /*%end*/]]></source>
			<p>
				しかし、上記のように書くのは冗長です。これを簡潔に記述するために、<a href="../reference/sqlfile.html#組み込み関数の使用">組み込み関数</a>の「@isNotEmpty」が使用できます。
				@isNotEmptyを使用すると次のように記述できます。
				これは上記のSQLと意味的にはまったく同等です。
			</p>
<source><![CDATA[select * from employee where /*%if @isNotEmpty(name) */ name = /* name */'hoge' /*%end*/]]></source>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
				メソッドの定義は、@isNotEmptyの使用の有無に影響されません。
			</p>
<source><![CDATA[@Select
List<Employee> selectByNotEmptyName(String name);]]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
			</p>
<source><![CDATA[List<Employee> list = dao.selectByNotEmptyName("SMITH");]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee where name = 'SMITH']]></source>
			<p>
				引数にnullや空文字を渡した場合、実行されるSQLは変化します。
			</p>
<source><![CDATA[list = dao.selectByNotEmptyName(null);]]></source>
<source><![CDATA[list = dao.selectByNotEmptyName("");]]></source>
			<p>
				引数にnullや空文字を渡した場合、SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee]]></source>
			<p>
				文字シーケンスを扱う組み込み関数には、「@isNotEmpty」の他に、「@isEmpty」、「@isBlank」、「@isNotBlank」があります。
				それぞれの説明については<a href="../reference/sqlfile.html#組み込み関数の使用">組み込み関数</a>を参照してください。
			</p>
		</section>
		<section name="ドメインによる検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestSelectByDomainメソッドを参照してください。
				ドメインを条件に使用した検索です。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
			</p>
<source><![CDATA[@Select
List<Employee> selectBySalary(Salary salary);]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectBySalary.sqlです。
				SQLは次のように記述されています。
				パラメータの型がドメインクラスであっても、SQLファイルでの扱い方は基本型と変わりません。
			</p>
<source><![CDATA[select * from employee where salary > /* salary */0]]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
			</p>
<source><![CDATA[List<Employee> list = dao.selectBySalary(new Salary(2900));]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee where salary > 2900]]></source>
		</section>
		<section name="エンティティによる検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestSelectByEntityメソッドを参照してください。
				エンティティを条件に使用した検索です。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
			</p>
<source><![CDATA[@Select
List<Employee> selectByExample(Employee e);]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectByExample.sqlです。
				SQLは次のように記述されています。
				パラメータの型がエンティティクラスの場合、SQLファイルの中ではドットを使用してエンティティのプロパティにアクセスできます。
			</p>
<source><![CDATA[select * from employee where name = /* e.name */'aaa']]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
			</p>
<source><![CDATA[Employee e = new Employee();
e.setName("SMITH");
List<Employee> list = dao.selectByExample(e);]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee where name = 'SMITH']]></source>
		</section>
		<section name="ページングを行う検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestOffsetLimitメソッドを参照してください。
				ページングを行う検索です。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
				Daoのメソッドでは、SelectOptions型のパラメータを定義します。
			</p>
<source><![CDATA[@Select
List<Employee> selectAll(SelectOptions options);]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectAll.sqlです。
				SQLは次のように記述されています。
				SQLにはORDER BY句の存在が必須です。
			</p>
<source><![CDATA[select * from employee order by id]]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
				SelectOptionsにoffsetとlimitを指定しています。
			</p>
<source><![CDATA[SelectOptions options = SelectOptions.get().offset(5).limit(3);
List<Employee> list = dao.selectAll(options);
assertEquals(3, list.size());]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee order by id limit 3 offset 5]]></source>
		</section>
		<section name="ページングと集計を同時に行う検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestCountメソッドを参照してください。
				ページングと集計（ページングしない場合の全件数の取得）を同時に行う検索です。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
				Daoのメソッドでは、SelectOptions型のパラメータを定義します。
			</p>
<source><![CDATA[@Select
List<Employee> selectAll(SelectOptions options);]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectAll.sqlです。
				SQLは次のように記述されています。
				SQLにはORDER BY句の存在が必須です。
			</p>
<source><![CDATA[select * from employee order by id]]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
				SelectOptionsのcountメソッドをあらかじめ呼び出しておきます。
				Daoのメソッドを呼び出した後、SelectOptionsのgetCountメソッドにより集計結果を取得できます。
			</p>
<source><![CDATA[SelectOptions options = SelectOptions.get().offset(5).limit(3).count();
List<Employee> list = dao.selectAll(options);
assertEquals(3, list.size());
assertEquals(14, options.getCount());]]></source>
			<p>
				SQLのログは次のように2つ出力されます。
			</p>
<source><![CDATA[select * from employee order by id limit 3 offset 5]]></source>
<source><![CDATA[select count(*) from ( select * from employee ) t_]]></source>
		</section>
		<section name="イテレーション検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestIterateメソッドを参照してください。
				SQLの結果セットを1件ずつエンティティなどのオブジェクトへインスタンス化する検索です。
				メモリの使用量を抑えながら大量データを扱う場合に向いています。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
				@Selectのiterate要素にtrueを指定し、DaoのメソッドではIterationCallback型のパラメータを定義します。
			</p>
<source><![CDATA[@Select(iterate = true)
<R> R selectByAge(int age, IterationCallback<R, Employee> callback);]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectByAge.sqlです。
				SQLは次のように記述されています。
			</p>
<source><![CDATA[select * from employee where age > /* age */0 order by age]]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
			</p>
<source><![CDATA[Salary sum = dao.selectByAge(30,
        new IterationCallback<Salary, Employee>() {

            private Salary sum = new Salary(0);

                @Override
                public Salary iterate(Employee target,
                        IterationContext context) {
                    Salary salary = target.getSalary();
                    if (salary != null) {
                        sum = sum.add(salary);
                    }
                    return sum;
                }
            });]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select * from employee where age > 30 order by age]]></source>
		</section>
		<section name="結合した結果を取得する検索">
			<p>
				<a href="https://www.seasar.org/svn/doma/trunk/doma-tutorial/src/test/java/tutorial/SelectTest.java">src/test/java/tutorial/SelectTest.java</a>のtestSelectJoinedResultメソッドを参照してください。
				結合した結果を取得する検索です。
				結合した結果が複数テーブルのカラムを含む場合、取得対象カラムすべてに対応するプロパティをもったエンティティクラスが必要です。
			</p>
			<p>
				使用するDaoのメソッド定義は次のとおりです。
			</p>
<source><![CDATA[@Select
List<EmployeeDepartment> selectAllEmployeeDepartment();]]></source>
			<p>
				戻り値のListの要素である<code>EmployeeDepartment</code>が結合した結果に対応するエンティティクラスです。
				このエンティティクラスは、結合のベースとなるテーブルに対応するエンティティクラスを継承すると比較的に簡単に作成できます。
			</p>
<source><![CDATA[@Entity
public class EmployeeDepartment extends Employee {

    @Column(name = "DEPARTMENT_NAME")
    String departmentName;

    ...

}]]></source>
			<p>
				Daoメソッドに対応するSQLファイルのパスはMETA-INF/tutorial/dao/EmployeeDao/selectAllEmployeeDepartment.sqlです。
				SQLは次のように記述されています。
			</p>
<source><![CDATA[select
  e.*,
  d.name department_name 
from 
  employee e 
left outer join 
  department d 
on 
  e.department_id = d.id 
order by 
  e.id]]></source>
			<p>
				Daoのメソッドは次のように呼び出します。
			</p>
<source><![CDATA[List<EmployeeDepartment> list = dao.selectAllEmployeeDepartment();]]></source>
			<p>
				SQLのログは次のように出力されます。
			</p>
<source><![CDATA[select
  e.*,
  d.name department_name 
from 
  employee e 
left outer join 
  department d 
on 
  e.department_id = d.id 
order by 
  e.id]]></source>
		</section>
	</body>
</document>