题外话:有n个小系统,如今须要用一个系统监控这n个系统中的数据。解决方案能够是把n个小系统中的数据都同步到一个大的数据库中,然而,这个并非最佳解决办法。java
我如今碰到一个问题,就是相似这样。每一个小系统的数据表,字段、字段类型彻底同样,实体类也是同样的,因而,我就想到用mybatis的多数据源切换来解决,因为这种用法并不常见。能在网上找的资料甚少,因而,查找API、源码,终于功夫不负有心人,找到了一种比较稳定的解决办法,写文以记之。spring
一、首先须要写出这n个数据源的配置,(这里以阿里巴巴的数据库链接池为例,dbcp的链接池我试过也是能够的)数据库
<bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="maxActive" value="${dbcp.maxActive}" /> <property name="maxIdle" value="${dbcp.maxIdle}" /> <property name="filters" value="stat,log4j" /> <property name="proxyFilters"> <list> <ref bean="stat-filter" /> <ref bean="log-filter" /> </list> </property> <property name="removeAbandoned" value="true"></property> <property name="removeAbandonedTimeout" value="${dbcp.removeAbandoned}"></property> <property name="connectionProperties"><value>clientEncoding=UTF8</value></property> <property name="testWhileIdle"><value>true</value></property> <property name="testOnBorrow"><value>false</value></property> <property name="testOnReturn"><value>false</value></property> <property name="validationQuery"><value>select sysdate from dual</value></property> <property name="validationQueryTimeout"><value>1</value></property> <property name="timeBetweenEvictionRunsMillis"><value>30000</value></property> <property name="numTestsPerEvictionRun"><value>20</value></property> </bean>
如此重复的配置n个不一样的数据源,以供切换。mybatis
二、数据源配置ui
<bean id="dataSource" class="com.xxx.common.spring.RoutingDataSourceSupport"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="dataSource1" value-ref="dataSource1"/><!-- 如此重复的配置n个须要切换的数据源 --> ... </map> </property> <property name="defaultTargetDataSource" ref="dataSource1"></property><!-- 设置默认的数据源 --> </bean>
三、RoutingDataSourceSupport方法url
package com.xxx.common.spring; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class RoutingDataSourceSupport extends AbstractRoutingDataSource { /** 日志句柄 */ private static Logger logger = LoggerFactory.getLogger(RoutingDataSourceSupport.class); private final static ThreadLocal<String> dataSourceKey = new ThreadLocal<String>(); /** * @param key * 设置当前的数据源 */ public static void setDataSource(String key) { dataSourceKey.set(key); } /** * 恢复默认的数据源 */ public static void clearDataSource() { dataSourceKey.set(null); } protected Object determineCurrentLookupKey() { String key = dataSourceKey.get(); logger.info("当前数据源:"+key); return key; } }
四、如何使用?spa
RoutingDataSourceSupport.setDataSource(dataSource); // 须要执行数据源切换的位置 do something.... RoutingDataSourceSupport.clearDataSource();
后记,也能够不使用日志
RoutingDataSourceSupport.clearDataSource();而直接使用
RoutingDataSourceSupport.setDataSource(null);