Spring多データソースの配置
大きなアプリケーションでは、データベースの水平伸縮性を向上させるために、複数のデータベース例を管理するために、多データソースを配置する必要がある.Springフレームが広く使われている今日は、Springの特性配置の動的多データを簡単に活用できます.
1.まずc 3 p 0.compboPooled DataSourceに基づくデータソースAを配置する.
daoContect.xml
daoContect.xml
実際の応用を究めて確かめる.以前は多くの応用が展開されていました.writeDataSourceとreadDataSourceとslaaveDataBaseの実現が、現在の大部分の応用は構造体にあまり適していません.ますますユーザとの相互性が重視され、データベース間の同期がますます複雑になり、メンテナンスが難しくなりました.もちろんこのような開発には、業務分野を分析する時間が必要です.どのような配置のデータ源を選ぶかは、業務と密接な関係があります.
1.まずc 3 p 0.compboPooled DataSourceに基づくデータソースAを配置する.
daoContect.xml
<bean id="dataSourceA" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url.a}?zeroDateTimeBehavior=convertToNull&characterEncoding=utf8"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="minPoolSize" value="${jdbc.miniPoolSize}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
<property name="initialPoolSize" value="${jdbc.initialPoolSize}"/>
<property name="maxIdleTime" value="${jdbc.maxIdleTime}"/>
<property name="acquireIncrement" value="${jdbc.acquireIncrement}"/>
<property name="acquireRetryAttempts" value="${jdbc.acquireRetryAttempts}"/>
<property name="acquireRetryDelay" value="${jdbc.acquireRetryDelay}"/>
<property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"/>
<property name="checkoutTimeout" value="${jdbc.checkoutTimeout}"/>
</bean>
2.次にデータソースBを追加します.daoContect.xml
<bean id="dataSourceB" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url.b}?zeroDateTimeBehavior=convertToNull&characterEncoding=utf8"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="minPoolSize" value="${jdbc.miniPoolSize}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
<property name="initialPoolSize" value="${jdbc.initialPoolSize}"/>
<property name="maxIdleTime" value="${jdbc.maxIdleTime}"/>
<property name="acquireIncrement" value="${jdbc.acquireIncrement}"/>
<property name="acquireRetryAttempts" value="${jdbc.acquireRetryAttempts}"/>
<property name="acquireRetryDelay" value="${jdbc.acquireRetryDelay}"/>
<property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"/>
<property name="checkoutTimeout" value="${jdbc.checkoutTimeout}"/>
</bean>
3.次にSpringから提供されるAbstractRoutingDataSourceを拡張し、Overrideの中のdetermine Currennt Look ukey方法でデータソースのrouteを実現する.
package datasource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource{
@Override
protected Object determineCurrentLookupKey() {
return CustomerContextHolder.getCustomerType();
}
}
その中のCustoomerContect Holderは開発者自身が実現したThreadLocalタイプのConttext Holderを封入したものです.
package datasource;
public class CustomerContextHolder {
public static final String DATA_SOURCE_A = "dataSourceA";
public static final String DATA_SOURCE_B = "dataSourceB";
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();
}
}
次は私達の上のdaoContect.xmlでこのDynamicData Source Beanを入れて、ターゲットData SourcesのMapマッピングを配置します.
<bean id="dynamicDataSource" class="datasource.DynamicDataSource" >
<!-- key-value -->
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSourceA" key="dataSourceA"></entry>
<entry value-ref="dataSourceB" key="dataSourceB"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSourceA" >
</property>
</bean>
4.どうやってこのダイナミックなマルチソースを使うのですか?実はとても簡単です.私達のDynamicDataSourceはAbstractRoutingDataSourceと継承しています.一方、AbstractRoutingDataSourceはorg.springframe ork.jdbc.datasource.AbstractDatasourceと同じように、明らかにAbstractDataSourceと同じように使いやすいです.ハイベルナーを例に挙げます.
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<!-- dataSource -->
<property name="dataSource" ref="dynamicDataSource" />
<property name="configLocations" value="classpath:hibernate.cfg.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</property>
</bean>
私たちが使っているのはまだsession Factoryです.事務管理の配置も以前と同じです.
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
DynamicDataSource Beanも容器の中にあります.残りはプログラムの中でどうやってコントロールしますか?欲しいデータソースを選んだらどうすればいいですか?
// dataSourceB.
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_B);
またはAOPを使って実現する
package datasource;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class DynamicDataSourceAspect {
@Pointcut("execution (public service.impl..*.*(..))")
public void serviceExecution(){}
@Before("serviceExecution()")
public void setDynamicDataSource(JoinPoint jp) {
for(Object o : jp.getArgs()) {
// , CustomerContextHolder.setCustomerType() DataSource
}
}
}
5.まとめ:AbstractRoutingDataSourceを使って、多くのデータソースを実現することができます.これからもっと多くのデータソースを拡張する時もとても簡単です.データソースを追加して、DynamicData Source BenのターゲットDataSources配置を修正すればいいです.あるデータソースの選択については、@AsppectでServiceの入り口にカットめん@Pointcutを追加し、@BeforeでJoinPointのクラス容が特定のデータソースを選択すると判断できます.実際の応用を究めて確かめる.以前は多くの応用が展開されていました.writeDataSourceとreadDataSourceとslaaveDataBaseの実現が、現在の大部分の応用は構造体にあまり適していません.ますますユーザとの相互性が重視され、データベース間の同期がますます複雑になり、メンテナンスが難しくなりました.もちろんこのような開発には、業務分野を分析する時間が必要です.どのような配置のデータ源を選ぶかは、業務と密接な関係があります.