<?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>Daoインタフェース</title>
	</properties>
	<body>
		<section name="目次">
			<ul>
				<li><a href="#概要">概要</a></li>
				<li><a href="#Dao定義">Dao定義</a>
					<ul>
						<li><a href="#継承">継承</a></li>
					</ul>
				</li>
				<li><a href="#クエリ定義">クエリ定義</a></li>
				<li><a href="#デリゲート定義">デリゲート定義</a>
					<ul>
						<li><a href="#ビルダを利用したSQLの組み立て">ビルダを利用したSQLの組み立て</a></li>
					</ul>
				</li>
				<li><a href="#Daoの利用方法">Daoの利用方法</a></li>
			</ul>
		</section>
		<section name="概要">
			<p>
				Data Access Object （Dao） はデータベースアクセスのためのインタフェースです。
			</p>
			<p>
				このページで説明するアノテーションはすべて <code>org.seasar.doma</code> パッケージに属します。
			</p>
		</section>
		<section name="Dao定義">
			<p>
				Daoは <a href="../apidocs/org/seasar/doma/Dao.html"><code>@Dao</code></a>が注釈されたインタフェースとして定義します。
				インタフェースはトップレベルのインタフェースでなければいけません（他のクラスやインタフェースにネストされていてはいけません）。
				インタフェースの実装クラスはaptによりコンパイル時に自動生成されます。
			</p>
<source>@Dao(config = AppConfig.class)
public interface EmployeeDao {
    ...
}</source>
			<p>
				<code>@Dao</code>の <code>config</code>要素には、
				<code>org.seasar.doma.jdbc.Config</code>の実装クラスを指定しなければいけません。
				<code>Config</code>の実装クラスは、データソース、データベースの方言、ネーミング規約等の<a href="config.html">設定</a>を行います。
			</p>
			<subsection name="継承">
				@Daoが注釈された他のDaoを1つのみ継承できます。
<source>@Dao(config = AppConfig.class)
public interface EmployeeDao {
    ...
}</source>
<source>@Dao(config = AppConfig.class)
public interface ParttimeEmployeeDao extends EmployeeDao {
    ...
}</source>
			</subsection>
		</section>
		<section name="クエリ定義">
			<p>
				SQLを問い合わせるクエリメソッドには、アノテーションが必須です。
				詳細は、<a href="query/index.html">クエリ</a>を参照してください。
			</p>
		</section>
		<section name="デリゲート定義">
			<p>
				Daoは、インタフェースであるためロジックをもつことができません。
				しかし、 <code>@Delegate</code>を注釈することで別のクラスに処理を委譲（デリゲート）できます。
				この機能は、JDBCのAPIやビルダのAPIを使ってSQLをプログラムで組み立てたい場合に使用するとよいでしょう。
			</p>
<source>@Dao(config = AppConfig.class)
public interface EmployeeDao {

    @Delegate(to = EmployeeDaoDelegate.class)
    int execute(Employee employee);
}</source>
			<p>
				<code>@Delegate</code> の <code>to</code>要素には、委譲先のクラスを指定します。
				委譲先のクラスの<code>public</code>なコンストラクタでは、<code>org.seasar.doma.jdbc.Config</code>を受け取るようにします。
			</p>
<source>public class EmployeeDaoDelegate {

    private Config config;
    
    public EmployeeDaoDelegate(Config config) {
        this.config = config;
    }

    public int execute(Employee employee) {
        DataSource dataSource = config.dataSource();
        ...
    }
}</source>
			<p>
				委譲先で委譲元のDaoインスタンスにアクセスしたい場合は、<code>public</code>なコンストラクタの2番目のパラメータで委譲元のDaoの型を受け取るようにします。
			</p>
<source>public class EmployeeDaoDelegate {

    private Config config;
    
    private EmployeeDao employeeDao;
    
    public EmployeeDaoDelegate(Config config, EmployeeDao employeeDao) {
        this.config = config;
        this.employeeDao = employeeDao;
    }

    public int execute(Employee employee) {
        ...
    }
}</source>
			<p>
				委譲先のクラスは次の制約を満たす必要があります。
			</p>
			<ul>
				<li><code>org.seasar.doma.jdbc.Config</code>を受け取るpublicなコンストラクタを持つ、もしくは、<code>org.seasar.doma.jdbc.Config</code>と委譲元のDaoを受け取るpublicなコンストラクタを持つ</li>
				<li>委譲元のメソッドと同じシグニチャのメソッドを持つ</li>
			</ul>
			<subsection name="ビルダを利用したSQLの組み立て">
				<p>
					<code>org.seasar.doma.jdbc.builder</code>パッケージでは、プログラムでSQLを組み立てるためのビルダクラスを提供しています。
					何らかの理由により<a href="#クエリ定義">クエリ定義</a>を利用した問い合わせが難しい場合にのみ、これらのビルダクラスを利用することを推奨します。
					また、ビルダクラスはデリゲート定義と組み合わせて使用することを推奨します。
				</p>
				<h4>検索</h4>
				<p>
					検索には、<code>SelectBuilder</code>クラスを使用します。
					このクラスのインスタンスは、<code>org.seasar.doma.jdbc.Config</code>型の引数をとる<code>static</code>な<code>newInstance</code>メソッドで生成できます。
					インスタンスには、<code>sql</code>メソッドでSQL文字列の断片を、<code>param</code>メソッドでパラメータの型とパラメータを渡せます。
				</p>
				<p>
					利用例は次のとおりです。
				</p>
<source><![CDATA[ SelectBuilder builder = SelectBuilder.newInstance(config);
 builder.sql("select");
 builder.sql("id").sql(",");
 builder.sql("name").sql(",");
 builder.sql("salary");
 builder.sql("from Emp");
 builder.sql("where");
 builder.sql("name like ").param(String.class, "S%");
 builder.sql("and");
 builder.sql("age > ").param(int.class, 20);
 Emp emp = builder.getSingleResult(Emp.class);]]></source>
				<p>
					組み立てたSQLの実行結果は、<code>getSingleResult</code>、<code>getResultList</code>、<code>iterate</code>のメソッドで処理できます。
					それぞれ、1件を処理したい場合、複数件を処理したい場合、複数件を1件ずつ処理したい場合に使用します。
				</p>
				<h4>挿入</h4>
				<p>
					挿入には、<code>InsertBuilder</code>クラスを使用します。
					このクラスのインスタンスは、<code>org.seasar.doma.jdbc.Config</code>型の引数をとる<code>static</code>な<code>newInstance</code>メソッドで生成できます。
					インスタンスには、<code>sql</code>メソッドでSQL文字列の断片を、<code>param</code>メソッドでパラメータの型とパラメータを渡せます。
				</p>
<source><![CDATA[ InsertBuilder builder = InsertBuilder.newInstance(config);
 builder.sql("insert into Emp");
 builder.sql("(name, salary)");
 builder.sql("values (");
 builder.param(String.class, "SMITH").sql(", ");
 builder.param(BigDecimal.class, new BigDecimal(1000)).sql(")");
 builder.execute();]]></source>
				<p>
					組み立てたSQLは<code>execute</code>メソッドで実行できます。
				</p>
				<h4>更新</h4>
				<p>
					更新には、<code>UpdateBuilder</code>クラスを使用します。
					このクラスのインスタンスは、<code>org.seasar.doma.jdbc.Config</code>型の引数をとる<code>static</code>な<code>newInstance</code>メソッドで生成できます。
					インスタンスには、<code>sql</code>メソッドでSQL文字列の断片を、<code>param</code>メソッドでパラメータの型とパラメータを渡せます。
				</p>
<source><![CDATA[ UpdateBuilder builder = UpdateBuilder.newInstance(config);
 builder.sql("update Emp");
 builder.sql("set");
 builder.sql("name = ").param(String.class, "SMIHT").sql(",");
 builder.sql("salary = ").param(BigDecimal.class, new BigDecimal("1000"));
 builder.sql("where");
 builder.sql("id = ").param(int.class, 10);
 builder.execute();
]]></source>
				<p>
					組み立てたSQLは<code>execute</code>メソッドで実行できます。
				</p>
				<h4>削除</h4>
				<p>
					削除には、<code>DeleteBuilder</code>クラスを使用します。
					このクラスのインスタンスは、<code>org.seasar.doma.jdbc.Config</code>型の引数をとる<code>static</code>な<code>newInstance</code>メソッドで生成できます。
					インスタンスには、<code>sql</code>メソッドでSQL文字列の断片を、<code>param</code>メソッドでパラメータの型とパラメータを渡せます。
				</p>
<source><![CDATA[ DeleteBuilder builder = DeleteBuilder.newInstance(config);
 builder.sql("delete from Emp");
 builder.sql("where");
 builder.sql("name = ").param(String.class, "SMITH");
 builder.sql("and");
 builder.sql("salary = ").param(BigDecimal.class, new BigDecimal(1000));
 builder.execute();]]></source>
				<p>
					組み立てたSQLは<code>execute</code>メソッドで実行できます。
				</p>
			</subsection>
		</section>
		<section name="Daoの利用方法">
			<p>
				コンパイルすると、aptにより実装クラスが生成されます。
				実装クラスをインスタンス化して使用してください。
				ただし、<a href="config.html#DIコンテナを利用する場合の設定例">設定クラスをDIコンテナで管理する</a>場合は、Daoのインスタンス化はアプリケーションのコードで行わずDIコンテナで制御してください。
			</p>
<source>EmployeeDao employeeDao = new EmployeeDaoImpl();
Employee employee = employeeDao.selectById(1);</source>
			<p>
				デフォルトでは、実装クラスの名前はインタフェースの名前に<code>Impl</code>をサフィックスしたものになります。
				パッケージやサフィックスを変更するには、<a href="apt.html">アノテーション処理</a>を参照してください。
			</p>
			<p>
				デフォルトコンストラクタを使用した場合は、<code>@Dao</code>の <code>config</code>要素に
				指定した設定により<code>javax.sql.DataSource</code>が決定されますが、
				特定の <code>DataSource</code>を指定してインスタンス化することも可能です。
			</p>
<source>DataSource dataSource = ...;
EmployeeDao employeeDao = new EmployeeDaoImpl(dataSource);
Employee employee = employeeDao.selectById(1);</source>
			<p>
				また、同様に<code>java.sql.Connection</code>を指定してインスタンス化することも可能です。
			</p>
<source>Connection connection = ...;
EmployeeDao employeeDao = new EmployeeDaoImpl(connection);
Employee employee = employeeDao.selectById(1);</source>
			<p>
				<code>DataSource</code>や<code>Connection</code>をコンストラクタに指定してインスタンス化する方法は、
				JDBCを直接利用した既存のアプリケーションで利用するのに適しています。
			</p>
			<p>
				Daoインタフェースはエンティティクラスと1対1で結びついているわけではありません。
				ひとつのDaoインタフェースで複数のエンティティクラスを扱えます。
			</p>
<source><![CDATA[@Dao(config = AppConfig.class)
public interface MyDao {
    @Select
    Employee selectEmployeeById(int id);
    @Select
    Department selectDepartmentByName(String name);
    @Update
    int updateAddress(Address address);
}]]></source>
		</section>
	</body>
</document>