■応用の森 Spring-MVC 複数のJDBCデータソースに接続する |
Spring-MVCのアプリケーションで、複数のDB(JDBCデータソース)に接続するテクニックをご紹介します。 通常は、一つの業務プロジェクトで扱うDBは、Olacleとか、MySQLとか、PostgreSQLとか、etc、、の どれか一種類のDBで運用されることがほとんどで、複数のDBで運用される想定はあまりする必要はありません。 でも、ごくたまに「2種類のDBを使いたい」とか宣ってくるクライアント様がいたりするので、 知っておくに越したことはないので、参考になるかわかりませんが、複数データソース接続方法をご紹介しておきます。 ここでの解説は、Spring-MVCでの接続テクニックです。 Spring Bootを使った、複数DB接続については、「応用の森 Spring Boot編」で改めてご紹介するつもりです。 |
JDBC接続の基本的な所は「■SpringMVC の小径 第8歩 あと一歩 DB連携」で説明してあります。 今回は、この基本形を複数接続用に改良する形で実現していますので まずここをよく理解してから取り組んでください。 とりあえず、このサンプルでは2種類のデータベースに接続する前提で解説していきます。 では、まずJDBCドライバ接続情報ファイル「WEBContent/WEB-INF/jdbc.properties」の改造(改良)を行います。 接続情報が2種類に増えたので、primary と secondary のキーワードを付けた接続情報を2種類定義しています。 この例では、プライマリDBがPostgreSQL。セカンダリDBが MariaDBという想定です。 なんでMariaDBなん? とか聞かれたら、だって私のサーバー(Fedora25)に勝手に付いてきてたからさ。 と答えておきます。 実際のDBの作成方法とかは、ここでは割愛しますので各自勉強してください。 以上で、JDBCドライバ接続情報ファイルの設定(改造)はおしまい。 引き続き、Spring-MVC設定ファイルのDB設定に進みます。 |
「■SpringMVC の小径 第8歩 あと一歩 DB連携」で説明した、 Spring-MVCのDB設定情報「WEBContent/WEB-INF/applicationContextDB.xml」の説明です。 ここでは、元々DataSourceのBean定義、SqlSessionFactoryのBean定義、TransactionManagerのBean定義 それと、XMLマッパーインターフェースのコンポーネント登録が1セット定義されていましたが これをプライマリ用と、セカンダリ用に、それぞれprimary、secondaryの接頭詞を付けて、 2セット定義しています。 この修正に伴い、XMLマッパーインターフェースと、MapperXMLファイルのロケーション(パッケージ階層)が それぞれ一階層深くなっています。 詳細は後述。 |
続いてMapper関連の説明ですが、このサンプルでは、 「■JSONぶらり旅」で使用したグラフ描画用Mapper GraphMapper.javaと、 「■SpringMVC の小径 第8歩 あと一歩 DB連携 8-3)XMLMapper」で使用したUserMapper.javaを例に挙げます。 元々は一つのDBにそれぞれ、tbl_graph、tbluserというテーブルがあり、これを読みだしていましたが、 DBの複数化に伴い、tbl_graphをプライマリDBに、tbluserをセカンダリDBに移動しました。 それに従って、Mapperインターフェースと、MapperXMLも混乱を避けるため、 パッケージ階層をプライマリ用、セカンダリ用に一段深くしたので、それに対する修正を行います。 プライマリ用MapperXML「WebContent/WEB-INF/mappers/primary/GraphMapper.xml」 大きな変更はありませんが、Mapperインタフェースを指定する、 namespaceのパッケージ階層で、primary が追加されています。 セカンダリ用MapperXML「WebContent/WEB-INF/mappers/secondary/UserMapper.xml」 こちらも同様に、Mapperインタフェースを指定する、 namespaceのパッケージ階層で、secondary が追加されています。 |
Mapperインターフェースも、primary/secondaryとパッケージ階層を一段深くしたので微修正を行います。 プライマリ用Mapperインターフェース「src/main/java/jp/dip/arimodoki/mapper/primary/GraphMapper.java」 セカンダリ用Mapperインターフェース「src/main/java/jp/dip/arimodoki/mapper/secondary/UserMapper.java」 どちらも内容に変更はありませんが、インターフェースの配置場所が変わったので、 パッケージ名が修正されています。 |
最後に、MapperインターフェースをDIするビジネスロジック(サービスロジック)の修正です。 プライマリ用DB処理ビジネスロジック「src/main/java/jp/dip/arimodoki/blogic/BlChartImpl.java」 セカンダリ用DB処理ビジネスロジック「src/main/java/jp/dip/arimodoki/blogic/BlUser.java」 これらも内容に大きな変更はありませんが、Mapperインターフェースのパッケージ階層が変わった事による import宣言の修正と、あとひとつ重要な修正点として、 @Transactionalアノテーションの使い方ですが、applicationContextDB.xmlでプライマリ用とセカンダリ用に TransactionManagerを分けたので、どちらのTransactionManagerを使うかを指定する必要があります。 プライマリ用のDBを操作するメソッドに、secondaryTransactionManager を指定しても Transactionは効かないので注意が必要です。 あと、一つのメソッドには一つの@Transactionalアノテーションしか指定できないので、 一つのメソッド内で、プライマリ/セカンダリ両方のDB操作を行う場合のTransactionはできないので、 そういう設計を行わないように注意する必要があります。 それ以外のコントローラ層や、View(HTL)は全く変更する必要はなく、そのまま使用可能です。 |
で、説明はここまでです。 ほんとは、コントローラーとView(HTML)も準備して、サンプル動かそうとも思ったのですが、 ※)ちゃんと動くことは確認していますが この散歩道のサイト上でプライマリ/セカンダリ設定を組み込むのがとても大事になってしまうので ここでは、説明のみとさせていただきます。 前述の通り、元々はすでに解説しているプログラムの改造なので それぞれ元の説明を見てもらえれば、コントローラやView(HTML)のサンプルも展示してありますので それらを有効活用して自分なりに挑戦してみてください。 Spring Boot 用の複数JDBCデータソースの実装方法は、また違ったやり方で実現できているので 「■応用の森 Spring Boot編 No001」で展示しています。 |
Spring-MVCの小技集 ![]() |
Spring-MVC 複数のJDBCデータソースに接続する |