-
背景
项目中需要访问本地及阿里云2个数据库。
环境为springmvc、mybatis、mysql、配置了tk.mybatis.mapper。 -
datasource.xml配置
<bean id="dataSourceTargetA" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" scope="singleton">
<property name="driverClass" value="${jdbc.a.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.a.url}" />
<property name="user" value="${jdbc.a.username}" />
<property name="password" value="${jdbc.a.password}" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
<property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
<property name="acquireRetryDelay" value="1000"></property>
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="60"></property>
<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。Default:
false -->
<property name="breakAfterAcquireFailure" value="false"></property>
</bean>
<bean id="dataSourceTargetB" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" scope="singleton">
<property name="driverClass" value="${jdbc.b.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.b.url}" />
<property name="user" value="${jdbc.b.username}" />
<property name="password" value="${jdbc.b.password}" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
<property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
<property name="acquireRetryDelay" value="1000"></property>
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="60"></property>
<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。Default:
false -->
<property name="breakAfterAcquireFailure" value="false"></property>
</bean>
<!-- 动态数据源 -->
<bean id="dynamicDataSource" class="com.test.util.DynamicDataSource" >
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSourceTargetA" key="dataSourceTargetA"></entry>
<entry value-ref="dataSourceTargetB" key="dataSourceTargetB"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSourceTargetA" >
</property>
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dynamicDataSource" />
</bean>
<!-- MyBatis ORM operation class -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dynamicDataSource" />
<property name="mapperLocations">
<list>
<value>classpath*:com/test/**/*Mapper.xml</value>
</list>
</property>
<property name="configLocation" value="classpath:provider-sql-map-config.xml" />
</bean>
- 添加动态数据源管理类
package com.test.util;
import com.test.util.CustomerContextHolder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 动态数据源管理类
* */
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return CustomerContextHolder.getCustomerType();
}
}
- 数据源切换
package com.test.util;
/**
* 数据源切换类
* */
public class CustomerContextHolder {
public static final String DATA_SOURCE_DEFAULT = "dataSourceTargetA";
public static final String DATA_SOURCE_B = "dataSourceTargetB";
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();
}
}
- 测试
//测试
@RequestMapping(value = "/cs", method = RequestMethod.POST)
@ResponseBody
public CommonResponse todaySelect(HttpServletRequest request, HttpServletResponse response,@RequestBody TabInfoSelectParam tabInfoSelectParam) throws Exception {
CommonResponse commonResponse = new CommonResponse();
//数据源B
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_B);
CarGpsRecord gpsRecord1 = new CarGpsRecord();
gpsRecord1.setCarGpsId(1989);
CarGpsRecord gpsRecord = carGpsRecordDAO.selectOne(gpsRecord1);
//切换默认数据源
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_DEFAULT);
Device device1 = new Device();
device1.setDevId(1201);
Device device = deviceDAO.selectOne(device1);
commonResponse.setData(gpsRecord);
return commonResponse;
}