ssm多数据源
最近一个项目需求是在同一个项目中同时调用不同的数据库,此时我想到了多数据源的方式来实现。
那么多数据源该如何实现呢?经过资料的查询,我发现一般是两种情况:1、采用手动切换;2、采用注解的方式切换
由于这个需求不大,所以采用手动方式进行切换
- 配置数据源:
<!-- 数据源配置, 使用 BoneCP 数据库连接池 -->
<!-- 数据库链接1 -->
<bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 数据库链接2 -->
<bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${us.jdbc.url}" />
<property name="username" value="${us.jdbc.username}" />
<property name="password" value="${us.jdbc.password}" />
</bean>
<!-- 数据库链接3 -->
<bean id="dataSource3" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${bbs.jdbc.url}" />
<property name="username" value="${bbs.jdbc.username}" />
<property name="password" value="${bbs.jdbc.password}" />
</bean>
<bean id="dataSource" class="com.common.utils.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- 指定lookupKey和与之对应的数据源 -->
<entry key="dataSource1" value-ref="dataSource1"></entry>
<entry key="dataSource2" value-ref="dataSource2"></entry>
<entry key="dataSource3" value-ref="dataSource3"></entry>
</map>
</property>
<!-- 这里可以指定默认的数据源 -->
<property name="defaultTargetDataSource" ref="dataSource1" />
</bean>
- 编写DynamicDataSource类
package com.common.utils;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
// 从自定义的位置获取数据源标识
return DynamicDataSourceHolder.getDataSource();
}
}
- 编写DynamicDataSourceHolder类
package com.common.utils;
public class DynamicDataSourceHolder {
/**
* 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
*/
private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>();
public static String getDataSource() {
//System.out.println("==================getDataSource:"+THREAD_DATA_SOURCE.get()+"=================");
return THREAD_DATA_SOURCE.get();
}
public static void setDataSource(String dataSource) {
//System.out.println("==================setDataSource:"+dataSource+"=================");
THREAD_DATA_SOURCE.set(dataSource);
}
public static void clearDataSource() {
THREAD_DATA_SOURCE.remove();
}
}
- 使用方法
public TUser query_ceshi() {
//切换数据源
DynamicDataSourceHolder.setDataSource(dataSource1);
return tUSerMapper.query_ceshi();
}
注:有时候切换的时候发现切换不回来,这个时候可以将切换信息(DynamicDataSourceHolder类中注释部分)打印出来,看一下调用的数据源是哪一个,这个就很清楚了;
等有时间继续研究注解方式实现。
愿我们漂泊半生,
归来仍少年!

浙公网安备 33010602011771号