using multiple databases with Spring iBatis
Spring経由でiBatisを使いつつ、複数のデータベースを利用しようと思ったら結構ハマったのでまとめておきます。
やりたいこと
- database1にはpersonというtableがあって、database2にはprojectというtableがあり、それぞれにアクセスしたい。
解決方法の概要
- database1, 2のそれぞれに対応するdataSourceを定義(dataSource1, dataSource2)
- dataSource1,2を用いるsqlMapClient(sqlMapClient1,2)とtransactionManager(transactionManager1,2)をそれぞれ定義
- sqlMapClient1,2内のconfigLocationは別ファイルにしておき(sqlmap-config-a.xml, sqlmap-config-b.xml)それぞれperson, projectテーブルに関するマッピングを定義
- SqlMapClientDaoSupportを継承しているDaoで、setSqlMapClient()する際に適切なsqlMapClientが利用されるようにする。
- たとえばアノテーションを用いてAutowireしているのであれば以下のような感じ
@Autowired @Qualifier("sqlMapClient1") public void injectSqlMapClient(SqlMapClient sqlMapClient) { setSqlMapClient(sqlMapClient); }
-
- これがかなり重要で、Spring, iBatisのバージョンが新しければそれっぽいエラーがでてくれるが、古めの場合は不適切なsqlMapClientがセットされるだけで進んでしまうので以下のようなエラーで悩むことになる
There is no statement named XXXXX in this SqlMap.
-
- あとUnit testでAbstractTransactionalJUnit4SpringContextTestsを使っている場合、dataSourceとかtransactionManagerとかが期待通りにセットされないので、以下のように指定する必要があるみたい
@TransactionConfiguration(transactionManager = "transactionManager1") public class TestSqlMapPersonDaoImpl extends AbstractTransactionalJUnit4SpringContextTests { : @Autowired @Qualifier("dataSource1") @Override public void setDataSource(DataSource dataSource) { super.setDataSource(dataSource); }
で、その辺を適当にまとめてサンプルっぽいものをおいておきました。
https://github.com/komamitsu/Spring-MVC-sample-using-iBatis
それにしても最近Springもまぁそんなに悪くないかなぁ、という感じになりつつありますね。分からないものだ。