spring2.0以后增加了AbstractRoutingDataSource这个东西提供动态切换数据源。
AbstractRoutingDataSource继承了AbstractDataSource,AbstractDataSource是javax.sql.DataSource的子类。
下面是一个动态切换数据源的例子:
1、在spring.xml配置文件配置
<!--配置连接池 -->
<bean id="readAndWriteDataSouce" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${driver}"/> <!-- 指定连接数据库的驱动 -->
<property name="jdbcUrl" value="${url}"/> <!-- 指定连接数据库的URL -->
<property name="user" value="${user}"/> <!-- 指定连接数据库的用户名 -->
<property name="password" value="${password}"/> <!-- 指定连接数据库的密码 -->
<property name="maxPoolSize" value="1000"/> <!-- 指定连接数据库连接池的最大连接数 -->
<property name="minPoolSize" value="100"/> <!-- 指定连接数据库连接池的最小连接数(生产使用时可改大些) -->
<property name="initialPoolSize" value="100"/> <!-- 指定连接数据库连接池的初始化连接数(生产使用时可改大些) -->
<property name="maxIdleTime" value="60"/> <!-- 指定连接数据库连接池的连接的最大空闲时间 -->
<!-- 当连接池连接耗尽时,客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。默认: 0 -->
<property name="checkoutTimeout" value="5000"/>
<property name="acquireIncrement" value="10"/> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireRetryDelay" value="100"/><!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
<property name="idleConnectionTestPeriod" value="60"/> <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
</bean>
<bean id="readDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${driver}"/>
<property name="jdbcUrl" value="${urlForRead}"/>
<property name="user" value="${userForRead}"/>
<property name="password" value="${passwordForRead}"/>
<property name="maxPoolSize" value="1000"/>
<property name="minPoolSize" value="100"/>
<property name="initialPoolSize" value="100"/>
<property name="maxIdleTime" value="60"/>
<property name="checkoutTimeout" value="5000"/>
<property name="acquireIncrement" value="10"/>
<property name="acquireRetryDelay" value="100"/>
<property name="idleConnectionTestPeriod" value="60"/>
</bean>
<!--MultipleDataSource是我们自己写的类继承AbstractRoutingDataSource类,实现动态数据源切换-->
<bean id="multipleDataSource" class="cn.hicard.common.MultipleDataSource">
<property name="defaultTargetDataSource" ref="readAndWriteDataSouce"/>
<property name="targetDataSources">
<map>
<entry key="defaultDataSource" value-ref="readAndWriteDataSouce"/>
<entry key="readDataSource" value-ref="readDataSource"/>
</map>
</property>
</bean>
2、创建动态切换数据源的实现类MultipleDataSource
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 多数据源支持, 再调用DAO之前, 执行MultipleDataSource.changeRead(); 更改为读 <br/>
* 读写数据源为默认数据源
*/
public class MultipleDataSource extends AbstractRoutingDataSource{
private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>();
/** 更改当前数据源为读数据源*/
public static void changeRead(){
dataSourceKey.set("readDataSource");
}
/*** 更改当前数据源为读写数据源,此数据源为默认数据源 */
public static void changeReadAndWirte(){
dataSourceKey.set("readAndWriteDataSouce");
}
//实现determineCurrentLookupKey方法这个是主要方法获取数据源
@Override
protected Object determineCurrentLookupKey() {
return dataSourceKey.get();
}
}
3、在调用数据库前切换到指定数据源即可
@Service
public class LogServiceImpl implements ILogService {
@Resource
private ILogDao logDao;
@Override
public List<Log> search(Map<String, Object> paramter)throws Exception {
MultipleDataSource.changeRead();//切换数据源
return logDao.search(paramter);
}
}