spring+myBatis 配置多数据源,切换数据源

转自:https://blog.youkuaiyun.com/qqhjqs/article/details/51553882

一个项目里一般情况下只会使用到一个数据库,但有的需求是要显示其他数据库的内容,像这样,我认为有两种做法

1、在使用另一个数据库的项目里写一些restful接口,满足移动端PC端的同时也满足其他应用调用数据的需求;

2、就是在项目里配置多数据源;

我现在就是要使用另一个数据库的数据,想到了以上两种方法,为了更加熟悉spring,我打算使用第二种方案;

我在百度上查了好多关于spring配置多数据源的blog,最后综合一些,总结一下,用最简洁,最直观的方法来实现这个功能


首先,单数据源配置流程如下


一个数据库对应一个dataSource,然后对应sqlSession,然后再在Dao层实现,配置如下

[html]  view plain  copy
  1.     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"    
  2.     destroy-method="close">    
  3.     <property name="driverClassName" value="${datasource.driver}" />    
  4.     <property name="url" value="${datasource.url}" />    
  5.     <property name="username" value="${datasource.username}" />    
  6.     <property name="password" value="${datasource.password}" />    
  7.     <property name="initialSize" value="${datasource.initialSize}"></property>    
  8.     <property name="maxActive" value="${datasource.maxActive}"></property>    
  9.     <property name="maxIdle" value="${datasource.maxIdle}"></property>    
  10.     <property name="minIdle" value="${datasource.minIdle}"></property>    
  11.     <property name="maxWait" value="${datasource.maxWait}"></property>    
  12. </bean>    
  13.   
  14. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">    
  15.     <property name="dataSource" ref="dataSource" />    
  16.     <property name="mapperLocations" value="classpath:com/iquant/simulated/mapping/*.xml"></property>    
  17. </bean>    
  18.   
  19. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">    
  20.     <property name="basePackage" value="com.iquant.simulated.dao" />    
  21.     <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>    
  22. </bean>   
  23.   
  24. <bean id="transactionManager"    
  25.     class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    
  26.     <property name="dataSource" ref="dataSource" />    
  27. </bean>    

但数据源就是这样的配置,数据库连接和一些属性的配置--->sqlSession配置--->映射文件哦欸之--->事物管理

如果是多数据源,有下面两种方案

A和B,先看看B,分别为两个数据源配置两个sqlSession,然后再Dao层实现,虽然功能实现了,但是到后期如果在增加多个数据源的话,修改复杂,维护起来也相当的麻烦,也不符合开闭原则;

A同样配置了两个dataSource,然后实现一个DynamicDataSource类,使用一个sqlSession,这样维护起来也非常的容易,我是用的就是A,配置起来相当简单!

毋庸置疑,两个dataSouce

[html]  view plain  copy
  1. <bean id="dataSourceSig" class="org.apache.commons.dbcp.BasicDataSource"    
  2.     destroy-method="close">    
  3.     <property name="driverClassName" value="${datasource.driver}" />    
  4.     <property name="url" value="${datasource.sig.url}" />    
  5.     <property name="username" value="${datasource.username}" />    
  6.     <property name="password" value="${datasource.password}" />    
  7.     <property name="initialSize" value="${datasource.initialSize}"></property>    
  8.     <property name="maxActive" value="${datasource.maxActive}"></property>    
  9.     <property name="maxIdle" value="${datasource.maxIdle}"></property>    
  10.     <property name="minIdle" value="${datasource.minIdle}"></property>    
  11.     <property name="maxWait" value="${datasource.maxWait}"></property>    
  12. </bean>   
  13.   
  14. <bean id="dataSourceSim" class="org.apache.commons.dbcp.BasicDataSource"    
  15.     destroy-method="close">    
  16.     <property name="driverClassName" value="${datasource.driver}" />    
  17.     <property name="url" value="${datasource.sim.url}" />    
  18.     <property name="username" value="${datasource.username}" />    
  19.     <property name="password" value="${datasource.password}" />    
  20.     <property name="initialSize" value="${datasource.initialSize}"></property>    
  21.     <property name="maxActive" value="${datasource.maxActive}"></property>    
  22.     <property name="maxIdle" value="${datasource.maxIdle}"></property>    
  23.     <property name="minIdle" value="${datasource.minIdle}"></property>    
  24.     <property name="maxWait" value="${datasource.maxWait}"></property>    
  25. </bean>   
然后配置自己实现的com.iquant.signal.configer.DynamicDataSource类,需指定默认的数据源,如使用其他再进行切换
[html]  view plain  copy
  1.             <bean id="dataSource" class="com.iquant.signal.configer.DynamicDataSource">      
  2. <property name="targetDataSources">      
  3.     <map key-type="java.lang.String">      
  4.         <entry value-ref="dataSourceSig" key="dataSourceSig"></entry>      
  5.         <entry value-ref="dataSourceSim" key="dataSourceSim"></entry>      
  6.     </map>      
  7. </property>    
  8. <!-- 默认使用dataSourceSig的数据源 -->    
  9. <property name="defaultTargetDataSource" ref="dataSourceSig"></property>         
  10. /bean>  
sqlSession和事物和之前一样,不用改动,实现DynamicDataSource类

[java]  view plain  copy
  1. public class DynamicDataSource extends AbstractRoutingDataSource {  
  2.     @Override  
  3.     protected Object determineCurrentLookupKey() {  
  4.         return DataSourceContextHolder.getDBType();  
  5.     }  
  6. }  
继承AbstractRoutingDataSource 重写determineCurrentLookupKey方法

实现DataSourceContextHolder类

[java]  view plain  copy
  1. public class DataSourceContextHolder {  
  2.     private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();      
  3.       
  4.     public static void setDBType(String dbType) {      
  5.         contextHolder.set(dbType);      
  6.     }      
  7.   
  8.     public static String getDBType() {      
  9.         return ((String) contextHolder.get());      
  10.     }      
  11.   
  12.     public static void clearDBType() {      
  13.         contextHolder.remove();      
  14.     }      
  15. }  
到此,多数据源就配置完成,如果想切换数据源,在代码操作对应数据库之前,加上此句代码

[java]  view plain  copy
  1. //注意这里在调用service前切换到dataSourceSim的数据源    
  2. // 经过测试可以写到serice层
  3. DataSourceContextHolder.setDBType("dataSouceSim");
  4. // 若要切换其他数据源,可能要想进行cleanDBType操作  
  5. DataSourceContextHolder.cleanDBType();
  6. // 然后再对其他数据源进行setDBType

这样就完成了多数据源的配置和切换功能,以后还有数据库添加,在配置一个dataSouce3.4.5.6.等等,就行了


参考BLOG

http://blog.youkuaiyun.com/wangpeng047/article/details/8866239

http://x125858805.iteye.com/blog/2061713


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值