データベースアクセス(共通編)
================================================================================
.. only:: html
.. contents:: 目次
:local:
:depth: 3
|
.. _data_access_overview-label:
Overview
--------------------------------------------------------------------------------
本節では、RDBMSで管理されているデータにアクセスする方法について、説明する。
O/R Mapperに依存する部分については、
* \ :doc:`DataAccessMyBatis3`\
を参照されたい。
|
JDBC DataSourceについて
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| RDBMSにアクセスする場合、アプリケーションからは、JDBCデータソースを参照してアクセスすることになる。
| JDBCデータソースを使用することにより、JDBCドライバーのロード、接続情報(接続URL、接続ユーザ、パスワードなど)の設定を、アプリケーションから排除することができる。
| そのため、アプリケーションからは、使用するRDBMSやデプロイする環境を、意識する必要がなくなる。
.. figure:: images_DataAccessCommon/dataaccess_common-datasource.png
:alt: about data source
:width: 90%
:align: center
\ **Picture - About JDBC DataSource**\
| JDBCデータソースの実装は、アプリケーションサーバ、OSSライブラリ、Third-Partyライブラリ、Spring Frameworkなどから提供されているので、プロジェクト要件や、デプロイ環境にあったデータソースの選定が必要になる。
| 以下に、代表的なデータソース3種類の紹介を行う。
* \ :ref:`datasource_application_server-label`\
* \ :ref:`datasource_oss_thirdparty-label`\
* \ :ref:`datasource_spring_framework-label`\
|
.. _datasource_application_server-label:
アプリケーションサーバ提供のJDBCデータソース
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
| Webアプリケーションでデータソースを使用する場合、アプリケーションサーバから提供されるJDBCデータソースを使うのが一般的である。
| アプリケーションサーバから提供されるJDBCデータソースは、コネクションプーリング機能など、Webアプリケーションで使うために必要な機能が、標準で提供されている。
.. tabularcolumns:: |p{0.10\linewidth}|p{0.35\linewidth}|p{0.55\linewidth}|
.. list-table:: **アプリケーションサーバから提供されているデータソース**
:header-rows: 1
:widths: 10 35 55
* - 項番
- アプリケーションサーバ
- 参照ページ
* - 1.
- Apache Tomcat \ |tomcat_major_version|\.\ |tomcat_minor_version|\
- | \ :url_tomcat:`The Tomcat JDBC Connection Pool `\ および
| \ :url_tomcat:`JNDI Datasource HOW-TO `\ (Apache Commons DBCP 2)を参照されたい。
|
.. _datasource_oss_thirdparty-label:
OSS/Third-Partyライブラリ提供のJDBCデータソース
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
| アプリケーションサーバから提供されるJDBCデータソースを使わない場合は、OSS/Third-Partyライブラリから提供されているJDBCデータソースを使用する。
| 本ガイドラインでは、「Apache Commons DBCP」を紹介する。他のライブラリを使用する場合は各自で調査されたい。
.. tabularcolumns:: |p{0.10\linewidth}|p{0.35\linewidth}|p{0.55\linewidth}|
.. list-table:: \ **OSS/Third-Partyライブラリから提供されているJDBCデータソース**\
:header-rows: 1
:widths: 10 35 55
* - 項番
- ライブラリ名
- 説明
* - 1.
- Apache Commons DBCP
- \ :url_commons_dbcp:`Apache Commons DBCP >`\ を参照されたい。
|
.. _datasource_spring_framework-label:
Spring Framework提供のJDBCデータソース
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
| Spring Frameworkから提供されているJDBCデータソースの実装クラスは、コネクションプーリング機能がないため、Webアプリケーションのデータソースとして使用する事はない。
| Spring Frameworkでは、JDBCデータソースの実装クラスと、JDBCデータソースのアダプタクラスを提供しているが、利用するケースが限定的なので、Appendixの\ :ref:`appendix_datasource_of_spring-label`\ として紹介する。
|
トランザクションの管理方法について
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Spring Frameworkの機能を使って、トランザクション管理を行う場合、プロジェクト要件や、デプロイ環境にあったPlatformTransactionManagerの選定が必要になる。
| 詳細は、\ :doc:`../../ImplementationAtEachLayer/DomainLayer`\ の\ :ref:`service_enable_transaction_management`\ を参照されたい。
|
トランザクション境界/属性の宣言について
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| トランザクション境界及びトランザクション属性の宣言は、Serviceにて、\ ``@Transactional``\ アノテーションを指定することで実現する。
| 詳細は、\ :doc:`../../ImplementationAtEachLayer/DomainLayer`\ の\ :ref:`service_transaction_management`\ を参照されたい。
|
データの排他制御について
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| データを更新する場合、データの一貫性および整合性を保障するために、排他制御を行う必要がある。
| データの排他制御については、\ :doc:`ExclusionControl`\ を参照されたい。
|
例外ハンドリングについて
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Spring Frameworkでは、JDBCの例外(\ ``java.sql.SQLException``\ )や、O/R Mapper固有の例外を、Spring Frameworkから提供しているデータアクセス例外(\ ``org.springframework.dao.DataAccessException``\ のサブクラス)に変換する機能がある。
| Spring Frameworkのデータアクセス例外へ変換しているクラスについては、Appendixの\ :ref:`appendix_dataaccessexception_converter_class-label`\ を参照されたい。
| 変換されたデータアクセス例外は、基本的にはアプリケーションコードでハンドリングする必要はないが、一部のエラー(一意制約違反、排他エラーなど)については、要件によっては、ハンドリングする必要がある。
| データアクセス例外をハンドリングする場合、\ ``DataAccessException``\ をcatchするのではなく、エラー内容を通知するサブクラスの例外をcatchすること。
| 以下に、アプリケーションコードでハンドリングする可能性がある代表的なサブクラスを紹介する。
.. tabularcolumns:: |p{0.10\linewidth}|p{0.35\linewidth}|p{0.55\linewidth}|
.. list-table:: \ **ハンドリングする可能性があるDBアクセス例外のサブクラス**\
:header-rows: 1
:widths: 10 35 55
* - 項番
- クラス名
- 説明
* - 1.
- | org.springframework.dao.
| DuplicateKeyException
- | 一意制約違反が発生した場合に発生する例外。
* - 2.
- | org.springframework.dao.
| OptimisticLockingFailureException
- | 楽観ロックに成功しなかった場合に発生する例外。他の処理によって同一データが更新されていた場合に発生する。
| 本例外は、O/R MapperとしてJPAを使用する場合に発生する例外である。MyBatisには楽観ロックを行う機能がないため、O/R Mapper本体から本例外が発生することはない。
* - 3.
- | org.springframework.dao.
| PessimisticLockingFailureException
- | 悲観ロックに成功しなかった場合に発生する例外。他の処理で同一データがロックされており、ロック解放待ちのタイムアウト時間を超えてもロックが解放されない場合に発生する。
.. note::
O/R MapperにMyBatisを使用して楽観ロックを実現する場合は、ServiceやRepositoryの処理として楽観ロック処理を実装する必要がある。
本ガイドラインでは、楽観ロックに失敗したことを、Controllerに通知する方法として、\ ``OptimisticLockingFailureException``\ およびその子クラスの例外を発生させることを推奨する。
理由は、アプリケーション層の実装(Controllerの実装)を、使用するO/R Mapperに依存させないためである。
下記は、一意制約違反を、ビジネス例外として扱う実装例である。
.. code-block:: java
try {
accountRepository.saveAndFlash(account);
} catch(DuplicateKeyException e) { // (1)
throw new BusinessException(ResultMessages.error().add("e.xx.yy.0002"), e); // (2)
}
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 90
* - 項番
- 説明
* - | (1)
- | 一意制約違反が発生した場合に発生する例外(DuplicateKeyException)をcatchする。
* - | (2)
- | データが重複している旨を伝えるビジネス例外を発生させている。
| 例外をcatchした場合は、必ず原因例外("\ ``e``\ ") をビジネス例外に指定すること。
|
複数データソースについて
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| アプリケーションによっては、複数のデータソースが必要になる場合がある。
| 以下に、複数のデータソースが必要になる代表的なケースを紹介する。
.. tabularcolumns:: |p{0.10\linewidth}|p{0.30\linewidth}|p{0.30\linewidth}|p{0.30\linewidth}|
.. list-table:: **複数のデータソースが必要になる代表的なケース**
:header-rows: 1
:widths: 10 30 30 30
* - 項番
- ケース
- 例
- 特徴
* - 1.
- データ(テーブル)の分類毎にデータベースやスキーマがわかれている場合。
- 顧客情報を保持するテーブル群と請求情報を保持するテーブル群が別々のデータベースやスキーマに格納されている場合など。
- 処理で扱うデータは決まっているので、静的に使用するデータソースを決定することができる。
* - 2.
- 利用者(ログインユーザ)によって使用するデータベースやスキーマが分かれている場合。
- 利用者の分類毎にデータベースやスキーマがわかれている場合など(マルチテナント等)。
- 利用者によって使用するデータソースが異なるため、動的に使用するデータソースを決定する必要がある。
|
.. _data-access-common_todo_multiple_datasource_overview:
共通ライブラリから提供しているクラスについて
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| 共通ライブラリから、以下の処理を行うクラスを提供している。
| 共通ライブラリの詳細については、以下を参照されたい。
* \ :ref:`data-access-common_appendix_like_escape`\
* \ :ref:`data-access-common_appendix_sequencer`\
|
How to use
--------------------------------------------------------------------------------
.. _data-access-common_howtouse_datasource:
データソースの設定
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
アプリケーションサーバで定義したDataSourceを使用する場合の設定
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
| アプリケーションサーバで定義したデータソースを使用する場合は、Bean定義ファイルに、JNDI経由で取得したオブジェクトをbeanとして登録するための設定を行う必要がある。
| 以下に、データベースはPostgreSQL、アプリケーションサーバはTomcat\ |tomcat_major_version|\.\ |tomcat_minor_version|\を使用する際の設定例を示す。
- \ :file:`xxx-context.xml`\ (Tomcatの設定ファイル)
.. code-block:: xml
.. tabularcolumns:: |p{0.10\linewidth}|p{0.10\linewidth}|p{0.80\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 10 80
* - 項番
- 属性名
- 説明
* - | (1)
- \-
- データソースを定義する。
* - |
- type
- リソースの種類を指定する。\ ``javax.sql.DataSource``\ を指定する。
* - |
- name
- リソース名を指定する。ここで指定した名前がJNDI名となる。
* - |
- driverClassName
- JDBCドライバクラスを指定する。例では、PostgreSQLから提供されているJDBCドライバクラスを指定する。
* - |
- url
- 接続URLを指定する。 【環境に合わせて変更が必要】
* - |
- username
- 接続ユーザ名を指定する。【環境に合わせて変更が必要】
* - |
- password
- 接続ユーザのパスワードを指定する。【環境に合わせて変更が必要】
* - |
- defaultAutoCommit
- 自動コミットフラグのデフォルト値を指定する。falseを指定する。トランザクション管理下であれば強制的にfalseになる。
* - | (2)
- \-
- | Tomcat\ |tomcat_major_version|\.\ |tomcat_minor_version|\の場合、factory属性を省略すると\ :url_commons_dbcp:`Apache Commons DBCP >`\ が使用される。
| 設定項目の詳細については、\ :url_commons_dbcp:`DBCP Configuration `\ を参照されたい。
.. tabs::
.. group-tab:: Java Config
- \ :file:`XxxEnvConfig.java`\
.. code-block:: java
@Bean(name = "dataSource")
public JndiObjectFactoryBean dataSource() {
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("jdbc/SampleDataSource"); // (3)
bean.setExpectedType(javax.sql.DataSource.class);
bean.setResourceRef(true);
return bean;
}
.. tabularcolumns:: |p{0.10\linewidth}|p{0.10\linewidth}|p{0.80\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 10 80
* - 項番
- 属性名
- 説明
* - | (3)
- \-
- データソースのJNDI名を指定する。Tomcatの場合は、データソース定義時のリソース名「(1)-name」に指定した値を指定する。
.. group-tab:: XML Config
- \ :file:`xxx-env.xml`\
.. code-block:: xml
.. tabularcolumns:: |p{0.10\linewidth}|p{0.10\linewidth}|p{0.80\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 10 80
* - 項番
- 属性名
- 説明
* - | (3)
- \-
- データソースのJNDI名を指定する。Tomcatの場合は、データソース定義時のリソース名「(1)-name」に指定した値を指定する。
|
Bean定義したDataSourceを使用する場合の設定
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
| アプリケーションサーバから提供されているデータソースを使わずに、
| OSS/Third-Partyライブラリから提供されているデータソースや、Spring Frameworkから提供されているJDBCデータソースを使用する場合は、Bean定義ファイルにDataSourceクラスのbean定義が必要となる。
| 以下に、データベースはPostgreSQL、データソースはApache Commons DBCPを使用する際の、設定例を示す。
.. tabs::
.. group-tab:: Java Config
- \ :file:`XxxEnvConfig.java`\
.. code-block:: java
@Bean(name = "dataSource", destroyMethod = "close")
public DataSource dataSourceDefault() {
BasicDataSource bean = new BasicDataSource(); // (1)
bean.setDriverClassName("org.postgresql.Driver"); // (2)
bean.setUrl("jdbc:postgresql://localhost:5432/macchinetta"); // (3)
bean.setUsername("postgres"); // (4)
bean.setPassword("postgres"); // (5)
bean.setDefaultAutoCommit(false); // (6)
// (7) (8)
return bean;
}
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 90
* - 項番
- 説明
* - | (1)
- データソースの実装クラスを指定する。例では、Apache Commons DBCPから提供されているデータソースクラス(\ ``org.apache.commons.dbcp2.BasicDataSource``\ )を指定する。
* - | (2)
- JDBCドライバクラスを指定する。例では、PostgreSQLから提供されているJDBCドライバクラスを指定する。
* - | (3)
- 接続URLを指定する。 【環境に合わせて変更が必要】
* - | (4)
- 接続ユーザ名を指定する。【環境に合わせて変更が必要】
* - | (5)
- 接続ユーザのパスワードを指定する。【環境に合わせて変更が必要】
* - | (6)
- 自動コミットフラグのデフォルト値を指定する。falseを指定する。トランザクション管理下であれば、強制的にfalseになる。
* - | (7)
- | BasicDataSourceには上記以外に、JDBC共通の設定値の指定、JDBCドライバー固有のプロパティ値の指定、コネクションプーリング機能の設定値の指定を行うことができる。
| 設定項目の詳細については、\ :url_commons_dbcp:`DBCP Configuration `\ を参照されたい。
* - | (8)
- | 設定例では値を直接指定しているが、環境によって設定値がかわる項目については、Placeholder(${...})を使用して、実際の設定値はプロパティファイルに指定すること。
| Placeholderについては、\ :url_spring_reference:`Spring Framework Documentation -Customizing Configuration Metadata with a BeanFactoryPostProcessor- `\ の\ ``Example: The Class Name Substitution PropertySourcesPlaceholderConfigurer``\ を参照されたい。
.. group-tab:: XML Config
- \ :file:`xxx-env.xml`\
.. code-block:: xml
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 90
* - 項番
- 説明
* - | (1)
- データソースの実装クラスを指定する。例では、Apache Commons DBCPから提供されているデータソースクラス(\ ``org.apache.commons.dbcp2.BasicDataSource``\ )を指定する。
* - | (2)
- JDBCドライバクラスを指定する。例では、PostgreSQLから提供されているJDBCドライバクラスを指定する。
* - | (3)
- 接続URLを指定する。 【環境に合わせて変更が必要】
* - | (4)
- 接続ユーザ名を指定する。【環境に合わせて変更が必要】
* - | (5)
- 接続ユーザのパスワードを指定する。【環境に合わせて変更が必要】
* - | (6)
- 自動コミットフラグのデフォルト値を指定する。falseを指定する。トランザクション管理下であれば、強制的にfalseになる。
* - | (7)
- | BasicDataSourceには上記以外に、JDBC共通の設定値の指定、JDBCドライバー固有のプロパティ値の指定、コネクションプーリング機能の設定値の指定を行うことができる。
| 設定項目の詳細については、\ :url_commons_dbcp:`DBCP Configuration `\ を参照されたい。
* - | (8)
- | 設定例では値を直接指定しているが、環境によって設定値がかわる項目については、Placeholder(${...})を使用して、実際の設定値はプロパティファイルに指定すること。
| Placeholderについては、\ :url_spring_reference:`Spring Framework Documentation -Customizing Configuration Metadata with a BeanFactoryPostProcessor- `\ の\ ``Example: The Class Name Substitution PropertySourcesPlaceholderConfigurer``\ を参照されたい。
|
トランザクション管理を有効化するための設定
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
トランザクション管理を有効化するための基本的な設定は、\ :doc:`../../ImplementationAtEachLayer/DomainLayer`\ の\ :ref:`service_enable_transaction_management`\ を参照されたい。
PlatformTransactionManagerについては、使用するO/R Mapperによって使うクラスがかわるので、詳細設定は、
* \ :doc:`DataAccessMyBatis3`\
を参照されたい。
|
JDBCのDebug用ログの設定
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| O/R Mapper(MyBatis)で出力されるログに発行したSQL等の詳細な情報が必要な場合、ログの出力設定を見直す必要がある。
| 以下に、logback.xmlに追加するO/R Mapperのログ出力設定を示す。
.. code-block:: xml
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 90
:class: longtable
* - 項番
- 説明
* - | (1)
- | \ ``xxxxxx.yyyyyy.zzzzzz``\ には、ログ出力対象のプロジェクトのグループIDを定義する。
| 上記の出力設定によって、出力されるログの例を以下に示す。
.. code-block:: console
level:DEBUG logger:j.c.n.f.s.f.d.r.dam3.TodoRepository.findByTodoId message:==> Preparing: SELECT todo_id ,category_id ,todo_title ,finished ,created_at ,version ,complete_at ,desc1 ,desc2 FROM t_todo WHERE todo_id = ?
level:DEBUG logger:j.c.n.f.s.f.d.r.dam3.TodoRepository.findByTodoId message:==> Parameters: 0000000001(String)
level:TRACE logger:j.c.n.f.s.f.d.r.dam3.TodoRepository.findByTodoId message:<== Columns: todo_id, category_id, todo_title, finished, created_at, version, complete_at, desc1, desc2
level:TRACE logger:j.c.n.f.s.f.d.r.dam3.TodoRepository.findByTodoId message:<== Row: 0000000001, 0000000001, Todo 1, f, 2016-12-24, 1, null, <>, desc21
level:DEBUG logger:j.c.n.f.s.f.d.r.d.T.findByTodoCategoryId message:====> Preparing: SELECT category_id ,name FROM m_todo_cat WHERE category_id = ?
level:DEBUG logger:j.c.n.f.s.f.d.r.d.T.findByTodoCategoryId message:====> Parameters: 0000000001(String)
level:TRACE logger:j.c.n.f.s.f.d.r.d.T.findByTodoCategoryId message:<==== Columns: category_id, name
level:TRACE logger:j.c.n.f.s.f.d.r.d.T.findByTodoCategoryId message:<==== Row: 0000000001, CA1
level:DEBUG logger:j.c.n.f.s.f.d.r.d.T.findByTodoCategoryId message:<==== Total: 1
level:DEBUG logger:j.c.n.f.s.f.d.r.dam3.TodoRepository.findByTodoId message:<== Total: 1
|
How to extend
--------------------------------------------------------------------------------
.. _data-access-common_todo_multiple_datasource_howtoextends:
動的にデータソースを切り替えるための設定
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| 複数のデータソースを定義し、動的に切り替えを行うには、\ ``org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource``\ を継承したクラスを作成し、どのような条件でデータソースを切り替えるかを実装する必要がある。
| 具体的には\ ``determineCurrentLookupKey``\ メソッドの戻り値となるキーとデータソースをマッピングさせることによって、これを実現する。キーの選択には通常、認証ユーザー情報、時間、ロケール等のコンテキスト情報を使用する。
AbstractRoutingDataSourceの実装
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
| \ ``AbstractRoutingDataSource``\ を拡張して作成した\ ``DataSource``\ を、通常のデータソースと同じように使用することでデータソースの動的な切り替えが実現できる。
| 以下に、時間によってデータソースを切り替える例を示す。
- \ ``AbstractRoutingDataSource``\ を継承したクラスの実装例
.. code-block:: java
package com.examples.infra.datasource;
import java.time.LocalTime
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.terasoluna.gfw.common.time.ClockFactory;
import jakarta.inject.Inject;
public class RoutingDataSource extends AbstractRoutingDataSource { // (1)
@Inject
ClockFactory clockFactory; // (2)
@Override
protected Object determineCurrentLookupKey() { // (3)
LocalTime localTime = LocalTime.now(clockFactory.fixed());
int hour = localTime.getHour();
return (7 <= hour && hour <= 23) ? "OPEN" : "CLOSE"; // (4)
}
}
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 90
* - 項番
- 説明
* - | (1)
- \ ``AbstractRoutingDataSource``\ を継承する。
* - | (2)
- 時刻を取得するため、\ ``ClockFactory``\ を使用する。詳細は、\ :doc:`../GeneralFuncDetail/SystemDate`\ を参照のこと。
* - | (3)
- \ ``determineCurrentLookupKey``\ メソッドを実装する。このメソッドの返り値と後述するbean定義ファイル内の\ ``targetDataSources``\ に定義した\ ``key``\ をマッピングすることにより使用するデータソースが決定される。
* - | (4)
- メソッド内で、コンテキスト情報(ここでは時間)を参照し、後述するbean定義ファイル内の\ ``targetDataSources``\ とマッピングさせるキーの切り替えを行う。ここは業務用件に合わせて実装する必要がある。このサンプルは、時刻が「7:00から23:59まで」と「0:00から6:59まで」で違うキーを返すように実装されている。
.. note::
認証ユーザー情報(IDや権限)によってデータソースを切り替えたい場合には、\ ``determineCurrentLookupKey``\ メソッド内で、\ ``org.springframework.security.core.context.SecurityContext``\ を使用して取得すれば良い。
\ ``org.springframework.security.core.context.SecurityContext``\ クラスの詳細は\ :doc:`../../Security/Authentication`\ を参照のこと。
|
データソースの定義
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
作成した\ ``AbstractRoutingDataSource``\ 拡張クラスをbean定義ファイルに定義する。
.. tabs::
.. group-tab:: Java Config
- \ :file:`XxxEnvConfig.java`\
.. code-block:: java
@Bean("routingDataSource")
public RoutingDataSource routingDataSource(
@Qualifier("dataSourceOpen") DataSource dataSourceOpen,
@Qualifier("dataSourceClose") DataSource dataSourceClose,
@Qualifier("dataSourceDefault") DataSource dataSourceDefault) {
RoutingDataSource bean = new RoutingDataSource(); // (1)
Map