配置文件:dataSource.xml,在ApplicationContext.xml中引入即可
<!-- 数据库管理 -->
<import resource ="classpath:dataSource.xml"/>
dataSource.xml 配置如下:以使用 阿里 druid数据源为例
<!-- 阿里 druid数据库连接池 -->
<bean id="dataSourceA" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<!-- 数据库基本信息配置 -->
<property name="url" value="jdbc:mysql://127.0.0.1:3306/a?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&allowMultiQueries=true" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="filters" value="stat" />
<!-- 最大并发连接数 -->
<property name="maxActive" value="20" />
<!-- 初始化连接数量 -->
<property name="initialSize" value="1" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 最小空闲连接数 -->
<property name="minIdle" value="10" />
<!-- 最大空闲连接数 -->
<property name="maxIdle" value="15" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 'x'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="maxOpenPreparedStatements" value="20" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
</bean>
<bean id="dataSourceB" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<!-- 数据库基本信息配置 -->
<property name="url" value="jdbc:mysql://127.0.0.1:3306/b?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&allowMultiQueries=true" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="filters" value="stat" />
<!-- 最大并发连接数 -->
<property name="maxActive" value="20" />
<!-- 初始化连接数量 -->
<property name="initialSize" value="1" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 最小空闲连接数 -->
<property name="minIdle" value="10" />
<!-- 最大空闲连接数 -->
<property name="maxIdle" value="15" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 'x'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="maxOpenPreparedStatements" value="20" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
</bean>
<!-- 动态配置数据源 -->
<bean id ="dataSource" class= "com.DataSource.DynamicDataSource" >
<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 >
<!-- 默认使用km的数据源 -->
<property name ="defaultTargetDataSource" ref= "dataSourceA"></property >
</bean >
<!-- 配置事务 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
数据库切换的工具类:用来切换数据库:
/**
* 数据库切换的工具类:用来切换数据库
* @ClassName: DataSourceContextHolder
* @Description: (这里用一句话描述这个类的作用)
* @author zhu
* @date 2017年3月28日 下午1:41:17
*
*/
public class DataSourceContextHolder {
// 线程本地环境
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
/**
* 设置数据源类型 参数来源:DataSourceType 类
* 使用1:DataSourceContextHolder.setDataSourceType(DataSourceType.SOURCE_ONE);
* 使用2:DataSourceContextHolder.setDataSourceType(DataSourceType.SOURCE_TWO);
* @Description(这里用一句话描述这个方法的作用)
* @return void
* @author zhu
*/
public static void setDataSourceType(String dbType) {
contextHolder.set(dbType);
}
// 获取数据源类型
public static String getDataSourceType() {
return ((String) contextHolder.get());
}
// 清除数据源类型
public static void clearDataSourceType() {
contextHolder.remove();
}
}import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 继承AbstractRoutingDataSource,并重写determineCurrentLookupKey()方法,来达到动态切换数据库
* 注意,这个类必须继承AbstractRoutingDataSource,且实现方法determineCurrentLookupKey,
* 该方法返回一个Object,一般是返回字符串:
* @ClassName: DynamicDataSource
* @Description: (这里用一句话描述这个类的作用)
* @author zhu
* @date 2017年3月28日 下午1:42:31
*
*/
public class DynamicDataSource extends AbstractRoutingDataSource{
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
/**
* 在进行DAO操作前,通过上下文环境变量,获得数据源的类型
* (non-Javadoc)
* @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#determineCurrentLookupKey()
*/
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceType();
}
}
/**
* 数据源ID 数据库类型常量类:必须与 xml配置中的value-ref的值保持一致
* @ClassName: DataSourceType
* @Description: (这里用一句话描述这个类的作用)
* @author zhu
* @date 2017年3月29日 下午1:20:30
*
*/
public class DataSourceType {
//127.0.0.1/A
public static final String SOURCE_ONE = "dataSourceA";
//127.0.0.1/B
public static final String SOURCE_TWO = "dataSourceB";
}