[Seasar-user:9069] Re: IPアドレスを渡しての動的なDB変更

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2007年 7月 10日 (火) 16:30:09 JST


小林 (koichik) です.

Date:    Tue, 10 Jul 2007 15:34:44 +0900
From:    大坪 淳一 <[E-MAIL ADDRESS DELETED]>
To:       [E-MAIL ADDRESS DELETED]
Subject: [Seasar-user:9067] IPアドレスを渡しての動的なDB変更

> getComponentでDaoを取得する時かSQL文を発行する時などに、
> IPアドレスを引数などで渡して動的にDBを指定してSQL文を
> 発行したいのですが可能でしょうか?
> 1台の親PCのDBのテーブルからIPアドレスを取得して、その
> IPアドレスのPC(子のPC)のDBに対してSQLを発行したいのですが…。

全然テストしていませんが,添付の XADataSourceImpl を
使って試してみてください.
設定の仕方は以下の通りです.

jdbc.dicon (S2.3 なら j2ee.dicon) にある MySQL 用の
XADataSourceImpl の定義があるので,
パッケージを org.seasar.extension.dbcp.imp から
sample (これは適当に変更してください) に変更します.
URL の指定は削除してください.

<component name="xaDataSource"
    class="sample.XADataSourceImpl"><!-- ここ -->
  <property name="driverClassName">"com.mysql.jdbc.Driver"</property>
  <property name="user">"xxx"</property>
  <property name="password">"xxx"</property>
</component>

ConnectionPoolImpl の定義があるので,
maxPoolSize プロパティの値を 0 にしてください.

<component name="connectionPool"
    class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
  <property name="timeout">600</property>
  <property name="maxPoolSize">0</property><!-- ここ -->
  <property name="allowLocalTx">true</property>
  <destroyMethod name="close"/>
</component>


プログラムでは,Dao にアクセスする前に
XADataSourceImpl の URL プロパティに
適切な値を設定してください.

public class Foo {
  private XADataSourceImpl xaDataSource;
  public void setXADataSource(XADataSourceImpl) {
    this.xaDataSource = xaDataSource;
  }

  public void hoge() {
    xaDataSource.setURL("jdbc:mysql://" + addr + ":3306/test");
    dao.select();
  }
}

こんな感じでできるんじゃないかと思います.

やっていることは,sample.XADataSourceImpl は
URL をスレッドローカルで持つようにして,
コネクションが必要になった場合は そのスレッドで
直前に setURL() された URL に接続するというものです.

ただし,コネクションがプールされてしまうと
ぐちゃぐちゃになってしまうので maxPoolSize を
0 にしてプールしないようにしています.

なお,トランザクション内では同じコネクションが
使われるので,setURL() しても効果はありません.

  public void hoge() {
    xaDataSource.setURL("jdbc:mysql://" + addr1 + ":3306/test");
    dao.select();
    xaDataSource.setURL("jdbc:mysql://" + addr2 + ":3306/test");
    dao.select();
  }

hoge() がトランザクション内で呼び出されると,
2 回目の Dao の呼び出しは最初の呼び出しと同じ
コネクション (addr1) が使われます.


ともあれ (JW),全然テストしていないので
何か問題があればまた質問してください.
あるいは要件が満たせないならまた相談してください.
その際は,お使いの S2 のバージョンや,もし
S2Dao を使っているならそのことも記述していただけると
助かります.



--
<signature>
   <name>Koichi Kobayashi</name>
   <e-mail>[E-MAIL ADDRESS DELETED]</e-mail>
</signature>
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: XADataSourceImpl.java
型:         application/octet-stream
サイズ:     4677 バイト
説明:       無し
URL:        http://ml.seasar.org/archives/seasar-user/attachments/20070710/7a6a3de2/attachment-0002.obj 


Seasar-user メーリングリストの案内