概要
Data Access Object (Dao) はデータベースアクセスのためのインタフェースです。
このページで説明するアノテーションはすべて org.seasar.doma
パッケージに属します。
Dao定義
Daoは @Dao
が注釈されたインタフェースとして定義します。
インタフェースはトップレベルのインタフェースでなければいけません(他のクラスやインタフェースにネストされていてはいけません)。
インタフェースの実装クラスはaptによりコンパイル時に自動生成されます。
@Dao(config = AppConfig.class) public interface EmployeeDao { ... }
@Dao
の config
要素には、
org.seasar.doma.jdbc.Config
の実装クラスを指定しなければいけません。
Config
の実装クラスは、データソース、データベースの方言、ネーミング規約等の設定を行います。
クエリ定義
SQLを問い合わせるクエリメソッドには、アノテーションが必須です。 詳細は、クエリを参照してください。
デリゲート定義
Daoは、インタフェースであるためロジックをもつことができません。
しかし、 @Delegate
を注釈することで別のクラスに処理を委譲(デリゲート)できます。
この機能は、JDBCのAPIやビルダのAPIを使ってSQLをプログラムで組み立てたい場合に使用するとよいでしょう。
@Dao(config = AppConfig.class) public interface EmployeeDao { @Delegate(to = EmployeeDaoDelegate.class) int execute(Employee employee); }
@Delegate
の to
要素には、委譲先のクラスを指定します。
委譲先のクラスのpublic
なコンストラクタでは、org.seasar.doma.jdbc.Config
を受け取るようにします。
public class EmployeeDaoDelegate { private Config config; public EmployeeDaoDelegate(Config config) { this.config = config; } public int execute(Employee employee) { DataSource dataSource = config.dataSource(); ... } }
委譲先で委譲元のDaoインスタンスにアクセスしたい場合は、public
なコンストラクタの2番目のパラメータで委譲元のDaoの型を受け取るようにします。
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) { ... } }
委譲先のクラスは次の制約を満たす必要があります。
org.seasar.doma.jdbc.Config
を受け取るpublicなコンストラクタを持つ、もしくは、org.seasar.doma.jdbc.Config
と委譲元のDaoを受け取るpublicなコンストラクタを持つ- 委譲元のメソッドと同じシグニチャのメソッドを持つ
ビルダを利用したSQLの組み立て
org.seasar.doma.jdbc.builder
パッケージでは、プログラムでSQLを組み立てるためのビルダクラスを提供しています。
何らかの理由によりクエリ定義を利用した問い合わせが難しい場合にのみ、これらのビルダクラスを利用することを推奨します。
また、ビルダクラスはデリゲート定義と組み合わせて使用することを推奨します。
検索
検索には、SelectBuilder
クラスを使用します。
このクラスのインスタンスは、org.seasar.doma.jdbc.Config
型の引数をとるstatic
なnewInstance
メソッドで生成できます。
インスタンスには、sql
メソッドでSQL文字列の断片を、param
メソッドでパラメータの型とパラメータを渡せます。
利用例は次のとおりです。
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);
組み立てたSQLの実行結果は、getSingleResult
、getResultList
、iterate
のメソッドで処理できます。
それぞれ、1件を処理したい場合、複数件を処理したい場合、複数件を1件ずつ処理したい場合に使用します。
挿入
挿入には、InsertBuilder
クラスを使用します。
このクラスのインスタンスは、org.seasar.doma.jdbc.Config
型の引数をとるstatic
なnewInstance
メソッドで生成できます。
インスタンスには、sql
メソッドでSQL文字列の断片を、param
メソッドでパラメータの型とパラメータを渡せます。
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();
組み立てたSQLはexecute
メソッドで実行できます。
更新
更新には、UpdateBuilder
クラスを使用します。
このクラスのインスタンスは、org.seasar.doma.jdbc.Config
型の引数をとるstatic
なnewInstance
メソッドで生成できます。
インスタンスには、sql
メソッドでSQL文字列の断片を、param
メソッドでパラメータの型とパラメータを渡せます。
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();
組み立てたSQLはexecute
メソッドで実行できます。
削除
削除には、DeleteBuilder
クラスを使用します。
このクラスのインスタンスは、org.seasar.doma.jdbc.Config
型の引数をとるstatic
なnewInstance
メソッドで生成できます。
インスタンスには、sql
メソッドでSQL文字列の断片を、param
メソッドでパラメータの型とパラメータを渡せます。
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();
組み立てたSQLはexecute
メソッドで実行できます。
Daoの利用方法
コンパイルすると、aptにより実装クラスが生成されます。 実装クラスをインスタンス化して使用してください。 ただし、設定クラスをDIコンテナで管理する場合は、Daoのインスタンス化はアプリケーションのコードで行わずDIコンテナで制御してください。
EmployeeDao employeeDao = new EmployeeDaoImpl(); Employee employee = employeeDao.selectById(1);
デフォルトでは、実装クラスの名前はインタフェースの名前にImpl
をサフィックスしたものになります。
パッケージやサフィックスを変更するには、アノテーション処理を参照してください。
デフォルトコンストラクタを使用した場合は、@Dao
の config
要素に
指定した設定によりjavax.sql.DataSource
が決定されますが、
特定の DataSource
を指定してインスタンス化することも可能です。
DataSource dataSource = ...; EmployeeDao employeeDao = new EmployeeDaoImpl(dataSource); Employee employee = employeeDao.selectById(1);
また、同様にjava.sql.Connection
を指定してインスタンス化することも可能です。
Connection connection = ...; EmployeeDao employeeDao = new EmployeeDaoImpl(connection); Employee employee = employeeDao.selectById(1);
DataSource
やConnection
をコンストラクタに指定してインスタンス化する方法は、
JDBCを直接利用した既存のアプリケーションで利用するのに適しています。
Daoインタフェースはエンティティクラスと1対1で結びついているわけではありません。 ひとつのDaoインタフェースで複数のエンティティクラスを扱えます。
@Dao(config = AppConfig.class) public interface MyDao { @Select Employee selectEmployeeById(int id); @Select Department selectDepartmentByName(String name); @Update int updateAddress(Address address); }