ホームページ >Java >&#&チュートリアル >Springのマルチデータソース構成についての深い理解
プロジェクト、特にデータ同期やスケジュールされたタスクなどのプロジェクトで複数のデータ ソースの問題がよく発生します。複数のデータ ソースに関する最大の悩みは、複数のデータ ソースを構成することではなく、データ ソースを柔軟かつ動的に切り替える方法です。たとえば、Spring および Hibernate Framework プロジェクトでは、Spring 構成でデータベースに接続するように dataSource を構成し、それを sessionFactory にバインドし、dao レイヤー コードで sessionFactory を指定してデータベース操作を実行することがよくあります。
上の図のように、それぞれのデータソースが複数ある場合は、下の図のようにするしかありません。
Dao レイヤーのコードに 2 つの SessionFactory がプログラムされていることがわかります。将来別のデータ ソースがある場合は、コードを変更して SessionFactory を追加する必要があることは明らかです。そしてクロージング原則。
その場合、正しいアプローチは次のとおりです:
1.applicationContext
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.1.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd"> <context:annotation-config /> <context:component-scan base-package="com"></context:component-scan> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:com/resource/config.properties</value> </list> </property> </bean> <bean id="dataSourceOne" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${dbOne.jdbc.driverClass}" /> <property name="jdbcUrl" value="${dbOne.jdbc.url}" /> <property name="user" value="${dbOne.jdbc.user}" /> <property name="password" value="${dbOne.jdbc.password}" /> <property name="initialPoolSize" value="${dbOne.jdbc.initialPoolSize}" /> <property name="minPoolSize" value="${dbOne.jdbc.minPoolSize}" /> <property name="maxPoolSize" value="${dbOne.jdbc.maxPoolSize}" /> </bean> <bean id="dataSourceTwo" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${dbTwo.jdbc.driverClass}" /> <property name="jdbcUrl" value="${dbTwo.jdbc.url}" /> <property name="user" value="${dbTwo.jdbc.user}" /> <property name="password" value="${dbTwo.jdbc.password}" /> <property name="initialPoolSize" value="${dbTwo.jdbc.initialPoolSize}" /> <property name="minPoolSize" value="${dbTwo.jdbc.minPoolSize}" /> <property name="maxPoolSize" value="${dbTwo.jdbc.maxPoolSize}" /> </bean> <bean id="dynamicDataSource" class="com.core.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry value-ref="dataSourceOne" key="dataSourceOne"></entry> <entry value-ref="dataSourceTwo" key="dataSourceTwo"></entry> </map> </property> <property name="defaultTargetDataSource" ref="dataSourceOne"> </property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dynamicDataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hbm2ddl.auto">create</prop> </props> </property> <property name="packagesToScan"> <list> <value>com.po</value> </list> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <aop:config> <aop:pointcut id="transactionPointCut" expression="execution(* com.dao..*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointCut" /> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="*" read-only="true" /> </tx:attributes> </tx:advice> <aop:config> <aop:aspect id="dataSourceAspect" ref="dataSourceInterceptor"> <aop:pointcut id="daoOne" expression="execution(* com.dao.one.*.*(..))" /> <aop:pointcut id="daoTwo" expression="execution(* com.dao.two.*.*(..))" /> <aop:before pointcut-ref="daoOne" method="setdataSourceOne" /> <aop:before pointcut-ref="daoTwo" method="setdataSourceTwo" /> </aop:aspect> </aop:config> </beans>rree
6. BrandDaoImpl.class
package com.core; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource{ @Override protected Object determineCurrentLookupKey() { return DatabaseContextHolder.getCustomerType(); } }7 .CityDaoImpl。 class
package com.core; public class DatabaseContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setCustomerType(String customerType) { contextHolder.set(customerType); } public static String getCustomerType() { return contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } }8. DaoTest.class
package com.core; import org.aspectj.lang.JoinPoint; import org.springframework.stereotype.Component; @Component public class DataSourceInterceptor { public void setdataSourceOne(JoinPoint jp) { DatabaseContextHolder.setCustomerType("dataSourceOne"); } public void setdataSourceTwo(JoinPoint jp) { DatabaseContextHolder.setCustomerType("dataSourceTwo"); } }
aop を使用して、目的のデータ ソースを動的に変更します。データ ソースを追加する必要がある場合、applicationContext 構成ファイルに aop 構成を追加し、新しい DataSourceInterceptor を作成するだけです。コードを変更することなく。
以上がこの記事の全内容です。皆さんの学習に役立つことを願っています。また、皆さんも PHP 中国語 Web サイトをサポートしていただければ幸いです。
Spring マルチデータ ソース構成関連記事をより深く理解するには、PHP 中国語 Web サイトに注目してください。