配置文件: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";
}