Javaでデータベースにアクセスするには、データソースを経由したコネクションプールを使うのが一般的です。
コネクションプールは通常、アプリケーションサーバが実装しますが、
Tomcatのようなトランザクションと連動するコネクションプールの実装のないアプリケーションサーバ用に
S2DBCPを用意しています。
データソースの設定は、jdbc.diconで行ないます。
jdbc.diconはクラスパスの通っているディレクトリ、
通常はWEB-INF/classesにおきます。
XADataSource、ConnectionPoolの設定をおこないます。
JDBC DriverがXADataSourceの機能を提供している場合は、 それをそのまま使えますが、
提供されていない場合、S2で用意しているXADataSourceImplを使って、XAの機能をエミュレートします。
org.seasar.extension.dbcp.impl.XADataSourceImpl
プロパティ |
説明 |
例 |
driverClassName |
JDBC Driverのクラス名 |
"oracle.jdbc.driver.OracleDriver" |
URL |
RDBMS固有のURL |
"jdbc:oracle:thin:@xxx:1521:yyy" |
user |
ユーザ名 |
"hoge" |
password |
パスワード |
"password" |
loginTimeout |
ログインタイムアウト時間 (秒単位) |
2 |
org.seasar.extension.dbcp.impl.ConnectionPoolImpl
プロパティ |
説明 |
例 |
XADataSource |
XADataSourceのインスタンスを設定します。S2Containerで設定する場合は、XADataSourceのコンポーネント名を設定します。
必須です。
|
xaDataSource |
transactionManager |
TransactionManagerのインスタンスを設定します。S2Containerで設定する場合は、TransactionManagerのコンポーネント名を設定します。
必須です。 |
TransactionManager |
timeout |
プールに戻されたコネクションがここで指定された秒数以上未使用だった場合、物理的にクローズされて破棄されます。
デフォルトは600(10分)です。 |
600 |
maxPoolSize |
同時にアクティブになれる コネクションの数を指定します。 この数を超える要求があると、コネクションがプールに返されるまで その要求はブロックされます。
0を設定するとコネクションはプールされず、コネクションの取得要求はブロックされません。
デフォルトは10です。 |
10 |
allowLocalTx |
JTAによって制御されない、JDBCのローカルトランザクションを許可する (true ) しない (false ) を指定します。
false を指定すると、JTAによるトランザクションが開始されていない状態でコネクションの取得が行われた場合に例外 (java.lang.IllegalStateException ) がスローされます。
開発時にfalse を指定すると、S2Txが提供するトランザクション・インターセプタの設定漏れを確実に検出することができます。
デフォルトはtrue です。 |
true |
validationQuery |
コネクションの死活を検証する際に使用するクエリを設定します。
null もしくは空文字を指定した場合、検証は行われません。
デフォルトはnull です。 |
"select * from dual" |
validationInterval |
プールから取得されるコネクションがここに指定した間隔(ミリ秒)よりも長い間プールされていた場合、コネクションの死活を検証します。
0以下の値を指定した場合、検証は行われません。
デフォルトは0です。 |
10000 |
コンポーネントの設定は以下のようになります。環境に合わせて書き換えてください。
jdbc.dicon
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components namespace="jdbc">
<include path="jta.dicon"/>
<include path="jdbc-extension.dicon"/>
<component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>
<component class="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory">
<arg>
<component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/>
</arg>
<property name="fetchSize">100</property>
<!--
<property name="maxRows">100</property>
-->
</component>
<component name="xaDataSource"
class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
<property name="driverClassName">
"oracle.jdbc.driver.OracleDriver"
</property>
<property name="URL">
"jdbc:oracle:thin:@xxx:1521:yyy"
</property>
<property name="user">"aaa"</property>
<property name="password">"bbb"</property>
</component>
<component name="connectionPool"
class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
<property name="timeout">600</property>
<property name="maxPoolSize">10</property>
<property name="allowLocalTx">true</property>
<property name="validationQuery">"select * from dual"</property>
<property name="validationInterval">10000</property>
<destroyMethod name="close"/>
</component>
<component name="dataSource"
class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>
</components>
一般的なアプリケーションサーバでは、JNDI経由(JndiResourceLocator)でデータソースを取得します。
jdbc.dicon
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components namespace="jdbc">
<include path="jta.dicon"/>
<include path="jdbc-extension.dicon"/>
<component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>
<component class="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory">
<arg>
<component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/>
</arg>
<property name="fetchSize">100</property>
<!--
<property name="maxRows">100</property>
-->
</component>
<component name="dataSource"
class="javax.sql.DataSource">
@org.seasar.extension.j2ee.JndiResourceLocator@lookup("JNDI名")
</component>
</components>
ユーザーの種類などにより動的にデータソースを切り替えたい場合は、SelectableDataSourceProxy とDataSourceFactory を利用します。
以下に、これらを利用するための設定とプログラムについて例を示します。
まず、データソースごとにjdbc.diconをコピーし、新しいdiconファイルを作成します。ここでは、jdbc-hoge.diconとjdbc-foo.diconという名前で作成します。
jdbc-hoge.dicon
<components namespace="jdbc">
<include path="jta.dicon"/>
<include path="jdbc-extension.dicon"/>
...
<component name="hogeDataSource"
class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>
</components>
jdbc-foo.dicon
<components namespace="jdbc">
<include path="jta.dicon"/>
<include path="jdbc-extension.dicon"/>
...
<component name="fooDataSource"
class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>
</components>
DataSource のコンポーネントにはデータソースごとに異なる名前をつけてください。そのとき、名前は「任意のプレフィックス + DataSource」としてください。
次に、新規作成したdiconファイルをjdbc.diconでインクルードし、さらにjdbc.diconにSelectableDataSourceProxy のコンポーネントを定義します。
jdbc.dicon
<components namespace="jdbc">
<include path="jdbc-hoge.dicon"/>
<include path="jdbc-foo.dicon"/>
<component name="dataSource" class="org.seasar.extension.datasource.impl.SelectableDataSourceProxy"/>
</components>
以上で、diconファイルの設定は完了です。
プログラムでは、org.seasar.extension.datasource.DataSourceFactory を使ってデータソース名を設定します。
データソース名の設定は、データソースが使用される前に行います。
通常は、インターセプタやServlet Filterで行うのが良いでしょう。
ここでは、インターセプタを使った例を示します。
サンプルコード
public class SelectDataSourceInterceptor implements MethodInterceptor {
private DataSourceFactory dataSourceFactory;
public void setDataSourceFactory(DataSourceFactory dataSourceFactory) {
this.dataSourceFactory = dataSourceFactory;
}
public Object invoke(MethodInvocation invocation) throws Throwable {
String currentName = dataSourceFactory.getSelectableDataSourceName();
try {
String dataSourceName = getDataSourceName();
dataSourceFactory.setSelectableDataSourceName(dataSourceName);
return invocation.proceed();
} finally {
dataSourceFactory.setSelectableDataSourceName(currentName);
}
public String getDataSourceName() {
//ユーザの種類に応じたデータソース名のプレフィックスを返す。
}
}
DataSourceFactory クラスのsetSelectableDataSourceName メソッドにはデータソース名のプレフィックスを渡してください。
この例では、hoge や foo がデータソース名のプレフィックスになります。
データソースを実際に利用する箇所では、単一のデータソースを扱う場合と変わらない方法でデータソースを利用できます。
|