コンフィグレーション
ここでは,Kuina-Daoで複数の永続ユニットを使用する場合や,Kuina-Daoをカスタマイズする方法について説明します.
異なった構成を持つ複数の永続ユニットの使用
異なった構成をもつ複数の永続ユニットを使用するには,以下の命名規約とパッケージ構成に従うことを推奨します. 推奨する命名規約とパッケージ構成に従うと,エンティティとマッピングファイルは対応する永続ユニットに自動的に登録されます.
- 推奨する命名規約
-
永続ユニット名は"
persistenceUnit
", もしくは"任意のプレフィックスPersistenceUnit
"とする.マッピングファイル名は"任意のプレフィックス
Orm.xml
"とする. - 推奨するパッケージ構成
-
永続ユニット"
persistenceUnit
"に属するエンティティは ルートパッケージ.entity
に配置する.永続ユニット"任意のプレフィックス
PersistenceUnit
"に属するエンティティは ルートパッケージ.entity
.任意のプレフィックスに配置する.永続ユニット"
persistenceUnit
"に属するマッピングファイルは ルートパッケージ.entity
,もしくはルートパッケージ.dao
に配置する.永続ユニット"任意のプレフィックス
PersistenceUnit
"に属するマッピングファイルは ルートパッケージ.entity
.任意のプレフィックス, もしくはルートパッケージ.dao
.任意のプレフィックスに配置する.
例
"persistenceUnit
"という名称の永続ユニットと
"hogePerisitenceUnit
"という名称の永続ユニットがそれぞれ存在する場合,
推奨されるパッケージ構成は次のようになります.
この例でのルートパッケージはkuina.dao.examle
とします.
Emp.class,Dept.class,Sales.classはエンティティとします.
また,登場するxmlファイルはすべてJPAのマッピングファイルとします.
kuina.dao.examle.dao.EmpDao.class
kuina.dao.examle.dao.EmpOrm.xml
kuina.dao.examle.dao.DeptDao.class
kuina.dao.examle.dao.DeptOrm.xml
kuina.dao.examle.dao.hoge.SalesDao.class
kuina.dao.examle.dao.hoge.SalesOrm.xml
kuina.dao.examle.entity.Emp.class
kuina.dao.examle.entity.Dept.class
kuina.dao.examle.entity.hoge.Sales.class
EmpOrm.xml
,DeptOrm.xml
,Emp.class
,
Dept.class
が永続ユニットpersistenceUnit
に登録されます.
残りの,SalesOrm.xml
,Sales.class
が
永続ユニットhogePerisitenceUnit
に登録されます.
同一の構成を持つ複数の永続ユニットの使用
同一の構成を持つ複数の永続ユニットを作成する場合,エンティティやDAOを共有したままコンテキストに応じて データベースの接続先を切り替えることができます.
推奨する命名規約とパッケージ構成に従えば,エンティティとマッピングファイルは対応する永続ユニットに 自動的に登録されます.
- 推奨する命名規約
-
永続ユニット名は"
persistenceUnit
"以外とする.マッピングファイル名は"任意のプレフィックス
Orm.xml
"とする. - 推奨するパッケージ構成
-
エンティティはルートパッケージ
.entity
に配置する.マッピングファイルはルートパッケージ
.entity
, もしくはルートパッケージ.dao
に配置する.
推奨する設定ファイル定義例
まずデータベースの接続先ごとにデータソースの設定を行います. この例ではH2とDerbyを使います. データベースごとの設定ファイルとそれを束ねるひとつの設定ファイルを用意します.
h2-jdbc.dicon
derby-jdbc.dicon
jdbc.dion
それぞれのファイルの定義は以下のようになります. 設定上の注意点は太字にしています. 一部定義を省略しています.
h2-jdbc.dicon
namespace
には"jdbc
"を指定します.
DataSource
を表すコンポーネントの名前は
"任意のプレフィックスDataSource
"にする必要があります.
ここでは"h2DataSource
"とします.
<components namespace="jdbc "> <include path="jta.dicon"/> <include path="jdbc-extension.dicon"/> ...(略)... <component name="h2DataSource " class="org.seasar.extension.dbcp.impl.DataSourceImpl" /> </components>
derby-jdbc.dicon
namespace
には"jdbc
"を指定します.
DataSource
を表すコンポーネントの名前は
"任意のプレフィックスDataSource
"にする必要があります.
ここでは"derbyDataSource
"とします.
<components namespace="jdbc "> <include path="jta.dicon"/> <include path="jdbc-extension.dicon"/> ...(略)... <component name="derbyDataSource " class="org.seasar.extension.dbcp.impl.DataSourceImpl" /> </components>
jdbc.dicon
データベースごとに用意した設定ファイルをインクルードします.
namespace
には"jdbc
"を指定します.
SelectableDataSourceProxy
を定義しコンポーネントの名前は
"dataSource
"とします.
<components namespace="jdbc "> <include path="h2-jdbc.dicon"/> <include path="derby-jdbc.dicon"/> <component name="dataSource " class="org.seasar.extension.datasource.impl.SelectableDataSourceProxy "/> </components>
次に永続ユニットごとの設定を用意します.
persistence.xml
jpa.dicon
h2-jpa.dicon
derby-jpa.dicon
それぞれの設定ファイルは以下のようになります (この例はJPA実装にHibernateを使う場合の設定です).
persistence.xml
永続ユニットを複数定義します. 接続先のデータベースは自動的に切り替えるのでデータソースは同じ名前でかまいません.
<persistence> <persistence-unit name="h2PersistenceUnit " transaction-type="JTA"> <jta-data-source>jdbc/dataSource</jta-data-source> ...(略)... </persistence-unit> <persistence-unit name="derbyPersistenceUnit " transaction-type="JTA"> <jta-data-source>jdbc/dataSource</jta-data-source> ...(略)... </persistence-unit> </persistence>
h2-jpa.dicon
永続ユニットh2PersistenceUnit
用の設定ファイルです.
ContainerPersistenceUnitProvider
のabstractUnitName
プロパティには
Seasar2でのデフォルトの永続ユニット名であるpersistenceUnit
を,
unitName
プロパティには実際の永続ユニットであるh2PersistenceUnit
を設定します.
unitName
プロパティの永続ユニットに自動で検出されたエンティティとマッピングファイルが登録されます.
EntityManager
を表すコンポーネントの名前は
"対応するデータソースのプレフィックスEntityManager
"にする必要があります.
<components> <include path="s2hibernate-jpa.dicon"/> <component name="h2PersistenceUnitProvider " class="org.seasar.framework.jpa.impl.ContainerPersistenceUnitProvider"> <property name="abstractUnitName">"persistenceUnit "</property> <property name="unitName">"h2PersistenceUnit "</property> </component> <component name="h2EntityManagerFactory " class="javax.persistence.EntityManagerFactory"> h2PersistenceUnitProvider .entityManagerFactory </component> <component name="h2EntityManager " class="org.seasar.framework.jpa.impl.TxScopedEntityManagerProxy"/> </components>
derby-jpa.dicon
永続ユニットderbyPersistenceUnit
用の設定ファイルです.
ContainerPersistenceUnitProvider
のabstractUnitName
プロパティには
Seasar2でのデフォルトの永続ユニット名であるpersistenceUnit
を,
unitName
プロパティには実際の永続ユニットであるderbyPersistenceUnit
を設定します.
unitName
プロパティの永続ユニットに自動で検出されたエンティティとマッピングファイルが登録されます.
EntityManager
を表すコンポーネントの名前は
"対応するデータソースのプレフィックスEntityManager
"にする必要があります.
<components> <include path="s2hibernate-jpa.dicon"/> <component name="derbyPersistenceUnitProvider " class="org.seasar.framework.jpa.impl.ContainerPersistenceUnitProvider"> <property name="abstractUnitName">"persistenceUnit "</property> <property name="unitName">"derbyPersistenceUnit "</property> </component> <component name="derbyEntityManagerFactory " class="javax.persistence.EntityManagerFactory"> derbyPersistenceUnitProvider .entityManagerFactory </component> <component name="derbyEntityManager " class="org.seasar.framework.jpa.impl.TxScopedEntityManagerProxy"/> </components>
jpa.dicon
永続ユニットごとに用意した設定ファイルをインクルードします.
SelectableEntityManagerProxy
を定義しコンポーネントの名前は
"entityManager
"とします.
<components> <include path="h2-jpa.dicon"/> <include path="derby-jpa.dicon"/> <component name="entityManager " class="org.seasar.framework.jpa.impl.SelectableEntityManagerProxy "/> </components>
実行方法
コンテキストを指定して接続先のデータベースを切り替えるには
org.seasar.extension.datasource.DataSourceFactory
コンポーネントの
setSelectableDataSourceName(String)
メソッドに,
データソースのプレフィックスを引数として渡して実行します.
例えば,上記の定義に従った場合,Derbyに接続するにはsetSelectableDataSourceName("derby")
を呼び出し,
H2に接続するにはsetSelectableDataSourceName("h2")
を呼び出します.
値を設定する場所としては,Servelet FilterやAOPのロジックが適しています.
Kuina-Daoのカスタマイズ
Kuina-Daoが提供するインターフェースを実装したクラスを作成し設定ファイルを適切に定義することでKuina-Daoをカスタマイズできます. たとえば,新しい機能を追加する場合次の作業が必要です.
- org.seasar.kuina.dao.internal.Commandインターフェースの実装クラスを作成する.
- org.seasar.kuina.dao.internal.CommandBuilderインターフェースの実装クラスを作成する.
- kuina-dao-builder.diconをコピーした設定ファイルにCommandBuilderの実装クラスを登録する.
- s2container.diconに上記で新しく作成した設定ファイルを使用することを指定する.
設定例
org.seasar.kuina.dao.internal.Command
の実装クラスの作成
Command
インタフェースを実装するクラスを作成しDAOメソッドに適応したい処理を記述します.
このクラスではEntityManager
に対し問い合わせや更新などを実行できます.
execute
メソッドの戻り値はDAOメソッドの戻り値となります.
DAOメソッドが戻り値を持たない場合,execute
メソッドではnull
を返してください.
public class HogeCommand implements Command { public Object execute(EntityManager em, Object[] arguments) { ... return null; } }
org.seasar.kuina.dao.internal.CommandBuilder
の実装クラスの作成
CommandBuilder
インターフェースを実装するクラスを作成しCommand
を生成するための処理を記述します.
build
メソッドはDAOメソッドのシグネチャ等の情報から対応するCommand
を生成します.
生成しない場合はnull
を返してください.
public class HogeCommandBuilder implements CommandBuilder { public Command build(Class<?> daoClass, Method method) { if (!method.getName().startsWith("hoge")) { return null; } ... return new HogeCommand(); } }
kuina-dao-builder.dicon
のコピーの作成
kuina-dao-x.x.x.jar
に同梱されているkuina-dao-builder.dicon
をコピーしてカスタマイズ用の設定ファイルを作成し,
新規に作成したCommandBuilder
を登録します.
たとえば,コピーしたファイルをmy-kuina-dao-builder.dicon
という名前にし
次のように新しいCommandBuilder
を定義します.
<components namespace="kuinaDaoBuilder"> <include path="convention.dicon"/> <include path="javaee5.dicon"/> <component class="org.seasar.kuina.dao.internal.metadata.DaoMetadataFactoryImpl"/> <component instance="prototype" class="org.seasar.kuina.dao.internal.metadata.DaoMetadataImpl"/> <component class="org.seasar.kuina.dao.internal.builder.SqlCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.SqlUpdateCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.NamedQueryCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.NamedQueryUpdateCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.FindAllQueryCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.ExampleQueryCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.DtoQueryCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.ParameterQueryCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.ConditionalQueryCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.FindCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.GetReferenceCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.ContainsCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.PersistCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.RemoveCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.MergeCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.RefreshCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.ReadLockCommandBuilder"/> <component class="org.seasar.kuina.dao.internal.builder.WriteLockCommandBuilder"/> <component class="kuina.dao.example.HogeCommandBuilder"/> </components>
s2container.diconの設定
S2Containerの振る舞いを制御する設定ファイルであるs2container.dicon
で
kuina-dao-builder.dicon
の替わりにカスタマイズ用の設定ファイルを使用することを指定します.
カスタマイズ用の設定ファイルがmy-kuina-dao-builder.dicon
という名前である場合,次のように記述します.
<components> <include condition="#ENV == 'ut'" path="hotdeploy.dicon"/> <include condition="#ENV != 'ut'" path="cooldeploy.dicon"/> <component class="org.seasar.framework.container.factory.SimplePathResolver"> <initMethod name="addRealPath"> <arg>"kuina-dao-builder.dicon "</arg> <arg>"my-kuina-dao-builder.dicon "</arg> </initMethod> </component> </components>