概要
Domaに対する設定は、Config
インタフェースの実装クラスで表現します。
Config
の実装クラスは@Dao
のconfig
要素に指定します。
次の事柄を設定で変更できます。
- データソース
- データソースの名前
- データベースの方言
- JDBC関連のログ出力に使用するロギングフレームワークへのアダプタ
- SQLファイルのキャッシュ戦略
- トランザクション属性がREQUIRES_NEWであるトランザクションとの連動方法
- 使用するアプリケーションサーバやフレームワークに依存した仕方でのクラスの取得
- 例外メッセージに含めるSQLのタイプ
- クエリ時に使用するパラメータ(タイムアウト、最大件数、フェッチ件数、バッチサイズ)
- Entityに定義が存在しないカラムが結果セットに含まれていた場合に無視するかどうか
設定クラスの作成
Configインタフェースを直接実装する場合
Config
インタフェースの実装クラスは、publicなデフォルトコンストラクタ(引数なしのコンストラクタ)を持たねばいけません。
また、どのメソッドも null
を返してはいけません。
ここでは、代表的な設定項目について説明します。
データソースの設定
javax.sql.DataSource
を、getDataSource
メソッドで返します。
学習等でごく簡易的なデータアクセスを行うだけであれば、
SimpleDataSource
を使用できます。
データソース名の設定
データソース名をあらわすString
を、getDataSourceName
メソッドで返します。
データソース名は、複数のデータソースを利用する環境で重要です。
データソース名はデータソースごとに自動生成される識別子を認識するために使用されます。
複数データソースを利用する場合は、それぞれ異なる名前を返すようにしてください。
RDBMS方言の設定
org.seasar.doma.jdbc.dialect.Dialect
を、getDialect
メソッドで返します。
Dialect
はRDBMSの方言をあらわすインタフェースです。
実装クラスには次のものがあります。
データベース | 方言クラスの名前 | 説明 |
---|---|---|
DB2 | org.seasar.doma.jdbc.dialect.Db2Dialect |
|
H2 Database Engine 1.2.126 | org.seasar.doma.jdbc.dialect.H212126Dialect |
H2 Database Engine 1.2.126で稼動実績あり |
H2 Database Engine | org.seasar.doma.jdbc.dialect.H2Dialect |
H2 Database Engine 1.3.171以降に対応 |
HSQLDB | org.seasar.doma.jdbc.dialect.HsqldbDialect |
|
Microsoft SQL Server 2008 | org.seasar.doma.jdbc.dialect.Mssql2008Dialect |
Microsoft SQL Server 2008に対応 |
Microsoft SQL Server | org.seasar.doma.jdbc.dialect.MssqlDialect |
Microsoft SQL Server 2012以降に対応 |
MySQL | org.seasar.doma.jdbc.dialect.MySqlDialect |
|
Oracle Database | org.seasar.doma.jdbc.dialect.OracleDialect |
|
PostgreSQL | org.seasar.doma.jdbc.dialect.PostgresDialect |
|
SQLite | org.seasar.doma.jdbc.dialect.SqliteDialect |
接続先のRDBMSにあわせて、実装クラスを選んでください。
ロガーの設定
org.seasar.doma.jdbc.JdbcLogger
を、getJdbcLogger
メソッドで返します。
JdbcLogger
はデータベースアクセスに関するログを扱うインタフェースです。
実装クラスには次のものがあります。
UtilLoggingJdbcLogger
は、java.util.logging
のロガーを使用してログ出力する実装です。
多くの場合、アプリケーションで使用するcommons-loggingなどのロガーに出力する実装クラスを別途作ったほうがよいでしょう。
SQLファイルのリポジトリの設定
org.seasar.doma.jdbc.SqlFileRepository
を、getSqlFileRepository
メソッドで返します。
SqlFileRepository
はSQLファイルのリポジトリを扱うインタフェースです。
実装クラスには次のものがあります。
GreedyCacheSqlFileRepository
は、読み込んだSQLファイルの内容をパースし、その結果をメモリが許す限り最大限にキャッシュします。
NoCacheSqlFileRepository
は、一切キャッシュを行いません。毎回、SQLファイルからSQLを読み取りパースします。
メモリの利用に厳しい制限がある環境や、扱うSQLファイルが膨大にある環境では、適切なキャッシュアルゴリズムをもった実装クラスを作成し使用してください。
REQUIRES_NEWの属性をもつトランザクションを制御するための設定
org.seasar.doma.jdbc.RequiresNewController
を、getRequiresNewController
メソッドで返します。
RequiresNewController
はREQUIRES_NEW の属性をもつトランザクションを制御するインタフェースです。
実装クラスには次のものがあります。
NullRequiresNewController
は、実質的になにも行いません。
REQUIRES_NEWの属性をもつトランザクションの最適な制御方法は、環境ごとに異なるため、適切な実装クラスを作成し使用してください。
ただし、このインタフェースは、@TableGenerator
で、識別子を自動生成する際にしか使われません。
@TableGenerator
を利用しない場合は、NullRequiresNewController
を使用してもかまいません。
また、@TableGenerator
を利用する場合であっても、識別子を採番するための更新ロックが問題にならない程度のトランザクション数であれば、NullRequiresNewController
を使用してもかまいません。
クラスの扱いに関する設定
org.seasar.doma.jdbc.ClassHelper
を、getClassHelper
メソッドで返します。
ClassHelper
はクラスの扱いに関してアプリケーションサーバやフレームワークの差異を抽象化するインタフェースです。
実装クラスには次のものがあります。
DefaultClassHelper
は、java.lang.Class.forName(name)
を用いてクラスをロードします。
例外メッセージに含めるSQLのタイプの設定
例外メッセージに含めるSQLのタイプをあらわす、org.seasar.doma.jdbc.ExceptionSqlLogType
をgetExceptionSqlLogType
メソッドで返します。
この値は、UniqueConstraintException
などの例外にどのような形式のSQLを含めるかを決定します。
クエリタイムアウト(秒)の設定
クエリタイムアウト(秒)をあらわす、int
をgetQueryTimeout
メソッドで返します。
この値は、Daoインタフェースの@Delegate
以外の問い合わせで使用されます。
クエリタイムアウト(秒)はjava.sql.Statement.setQueryTimeout(int)
に渡されます。
SELECT時のフェッチサイズの設定
SELECT時のフェッチサイズをあらわす、int
をgetFetchSize
メソッドで返します。
この値は、Daoインタフェースの@Select
が注釈されたメソッドの実行で使用されます。
フェッチサイズはjava.sql.Statement.setFetchSize(int)
に渡されます。
SELECT時の最大行数の設定
SELECT時の最大行数をあらわす、int
をgetMaxRows
メソッドで返します。
この値は、Daoインタフェースの@Select
が注釈されたメソッドの実行で使用されます。
最大行数はjava.sql.Statement.setMaxRows(int)
に渡されます。
バッチ更新のバッチサイズの設定
バッチサイズをあらわす、int
をgetBatchSize
メソッドで返します。
この値は、Daoインタフェースの@BatchUpdate
などが注釈されたバッチ系のメソッドの実行に使用されます。
Entityに定義が存在しないカラムが結果セットに含まれていた場合に無視するかどうか
無視するかどうかをあらわすboolean
をignoreUnknownColumn
メソッドで返します。
true
を返すと、org.seasar.doma.jdbc.MappedPropertyNotFoundException
のスローを抑制できます。
この値は、Daoインタフェースの@Select
が注釈されたメソッドの実行に使用されます。
DomaAbstractConfigを継承する場合
Config
インタフェースを直接実装してもかまいませんが、
いくつかのデフォルトの設定をもつ DomaAbstractConfig
を継承するのが簡単です。
最初は、このクラスを使い、慣れてきたらConfig
インタフェースを直接実装するのがよいでしょう。
public class AppConfig extends DomaAbstractConfig { ... }
DomaAbstractConfig
を利用する場合、必要な設定は次の3つです。
- データソースの設定
- データソース名の設定
- RDBMS方言の設定
上記以外の設定については、デフォルトの実装やデフォルトの値が使用されます。
設定項目 | デフォルトの実装クラス/値 |
---|---|
ロガーの設定 | org.seasar.doma.jdbc.UtilLoggingJdbcLogger |
SQLファイルのリポジトリの設定 | org.seasar.doma.jdbc.GreedyCacheSqlFileRepository |
REQUIRES_NEWの属性をもつトランザクションを制御するための設定 | org.seasar.doma.jdbc.NullRequiresNewController |
クラスの扱いに関する設定 | org.seasar.doma.jdbc.DefaultClassHelper |
例外メッセージに含めるSQLのタイプの設定 | org.seasar.doma.jdbc.ExceptionSqlLogType.FORMATTED_SQL |
クエリタイムアウト(秒)の設定 | 0 (0以下の値は明示的に設定しないことをあらわします) |
SELECT時のフェッチサイズの設定 | 0 (0以下の値は明示的に設定しないことをあらわします) |
SELECT時の最大行数の設定 | 0 (0以下の値は明示的に設定しないことをあらわします) |
バッチ更新のバッチサイズの設定 | 10 |
Entityに定義が存在しないカラムが結果セットに含まれていた場合に無視するかどうか | false |
JDBCドライバの設定
通常、クラスパスが通っていれば、JDBC 4.0 ドライバはサービスプロバイダメカニズムにより自動でロードされます。
しかし、たとえばTomcatでは、WEB-INF/libの下のJDBCドライバを自動でロードしません。 自動でロードされない条件下では、Class.forNameを使ってJDBCドライバをロードしてください。
Class.forNameを実行する場所は、設定クラスのstatic初期化子が1つの候補です。 たとえば、H2 DatabaseのJDBCドライバを明示的にロードする場合には次のようにします。
public class AppConfig extends DomaAbstractConfig { static { try { Class.forName("org.h2.Driver"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } ... }
設定クラスの利用
設定クラスは@Dao
のconfig
要素で指定します。
設定クラスをAppConfig
という名前で作成した場合、次のようになります。
@Dao(config = AppConfig.class) public interface EmployeeDao { ... }
DIコンテナを利用する場合の設定例
DIコンテナを利用する場合、Dao
の実装クラスや設定クラスのインスタンスをDIコンテナに管理させるとよいでしょう。
設定クラスのインスタンスのインジェクション
Dao
の実装クラスのインスタンスに設定クラスのインスタンスをインジェクションするには、
@Dao
のconfig
要素に何も指定しないでください。
この場合、Config
型のインスタンスを受け取るコンストラクタがDao
の実装クラスに生成されます。
コンストラクタインジェクションをサポートするDIコンテナであれば、設定ファイルなどによりインジェクションが可能です。
@Dao public interface EmployeeDao { ... }
上のインタフェースに対する実装クラスのソースコードは、aptにより次のように生成されます。
public class EmployeeDaoImpl extends org.seasar.doma.jdbc.DomaAbstractDao implements example.EmployeeDao { public EmployeeDaoImpl(org.seasar.doma.jdbc.Config config) { super(config); } ... }
aptにより生成されるソースコードに対するアノテーションの注釈
@AnnotateWith
を使用することで、インジェクションのためのアノテーションをDao
の実装クラスのソースコードに注釈できます。
これにより、DIコンテナがサポートしていれば、アノテーションによるインジェクションも可能になります。
たとえば、 Guiceのアノテーションを注釈するには次のように記述します。
@Dao @AnnotateWith(annotations = { @Annotation(target = AnnotationTarget.CONSTRUCTOR, type = Inject.class), @Annotation(target = AnnotationTarget.CONSTRUCTOR_PARAMETER, type = Named.class, elements = "\"sales\"") }) public interface EmployeeDao { ... }
上のインタフェースに対する実装クラスのソースコードは、aptにより次のように生成されます。 コンストラクタとコンストラクタのパラメータにアノテーションが注釈されていることに注目してください。
public class EmployeeDaoImpl extends org.seasar.doma.jdbc.DomaAbstractDao implements example.EmployeeDao { @com.google.inject.Inject() public EmployeeDaoImpl(@com.google.inject.name.Named("sales") org.seasar.doma.jdbc.Config config) { super(config); } ... }
@AnnotateWith
を任意のアノテーションに注釈し、そのアノテーションをDaoインタフェースに注釈することも可能です。
たとえば、@InjectConfig
というアノテーションに@AnnotateWith
を注釈するとします。
@AnnotateWith(annotations = { @Annotation(target = AnnotationTarget.CONSTRUCTOR, type = Inject.class), @Annotation(target = AnnotationTarget.CONSTRUCTOR_PARAMETER, type = Named.class, elements = "\"sales\"") }) public @interface InjectConfig { ... }
@InjectConfig
をDaoインタフェースに注釈すれば、@AnnotateWith
を直接Daoインタフェースに注釈しているのと同じ効果が得られます。
@Dao @InjectConfig public interface EmployeeDao { ... }