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


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

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

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

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

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

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

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

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="${datasource.driver}" />
    <property name="url" value="${datasource.url}" />
    <property name="username" value="${datasource.username}" />
    <property name="password" value="${datasource.password}" />
    <property name="initialSize" value="${datasource.initialSize}"></property>
    <property name="maxActive" value="${datasource.maxActive}"></property>
    <property name="maxIdle" value="${datasource.maxIdle}"></property>
    <property name="minIdle" value="${datasource.minIdle}"></property>
    <property name="maxWait" value="${datasource.maxWait}"></property>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="mapperLocations" value="classpath:com/iquant/simulated/mapping/*.xml"></property>
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.iquant.simulated.dao" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>

    <bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
    </bean>
    但数据源就是这样的配置,数据库连接和一些属性的配置--->sqlSession配置--->映射文件哦欸之--->事物管理

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

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

    我们分别配置了两个 dataSource,两个sqlSessionFactory,两个transactionManager,以及关键的地方在于MapperScannerConfigurer 的配置——使用sqlSessionFactoryBeanName属性,注入不同的sqlSessionFactory的名称,这样的话,就为不同的数据库对应的 mapper 接口注入了对应的 sqlSessionFactory。

    需要注意的是,多个数据库的这种配置是不支持分布式事务的,也就是同一个事务中,不能操作多个数据库。这种配置方式的优点是很简单,但是却不灵活。

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

    毋庸置疑,两个dataSouce

    <bean id="dataSourceSig" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="${datasource.driver}" />
    <property name="url" value="${datasource.sig.url}" />
    <property name="username" value="${datasource.username}" />
    <property name="password" value="${datasource.password}" />
    <property name="initialSize" value="${datasource.initialSize}"></property>
    <property name="maxActive" value="${datasource.maxActive}"></property>
    <property name="maxIdle" value="${datasource.maxIdle}"></property>
    <property name="minIdle" value="${datasource.minIdle}"></property>
    <property name="maxWait" value="${datasource.maxWait}"></property>
    </bean>

    <bean id="dataSourceSim" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="${datasource.driver}" />
    <property name="url" value="${datasource.sim.url}" />
    <property name="username" value="${datasource.username}" />
    <property name="password" value="${datasource.password}" />
    <property name="initialSize" value="${datasource.initialSize}"></property>
    <property name="maxActive" value="${datasource.maxActive}"></property>
    <property name="maxIdle" value="${datasource.maxIdle}"></property>
    <property name="minIdle" value="${datasource.minIdle}"></property>
    <property name="maxWait" value="${datasource.maxWait}"></property>
    </bean>
    然后配置自己实现的com.iquant.signal.configer.DynamicDataSource类,需指定默认的数据源,如使用其他再进行切换
    <bean id="dataSource" class="com.iquant.signal.configer.DynamicDataSource">
    <property name="targetDataSources">
    <map key-type="java.lang.String">
    <entry value-ref="dataSourceSig" key="dataSourceSig"></entry>
    <entry value-ref="dataSourceSim" key="dataSourceSim"></entry>
    </map>
    </property>
    <!-- 默认使用dataSourceSig的数据源 -->
    <property name="defaultTargetDataSource" ref="dataSourceSig"></property>
    </bean>
    sqlSession和事物和之前一样,不用改动,实现DynamicDataSource类
    public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
    return DataSourceContextHolder.getDBType();
    }
    }
    继承AbstractRoutingDataSource 重写determineCurrentLookupKey方法
    实现DataSourceContextHolder类

    public class DataSourceContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

    public static void setDBType(String dbType) {
    contextHolder.set(dbType);
    }

    public static String getDBType() {
    return ((String) contextHolder.get());
    }

    public static void clearDBType() {
    contextHolder.remove();
    }
    }
    到此,多数据源就配置完成,如果想切换数据源,在代码操作对应数据库之前,加上此句代码
    //注意这里在调用service前切换到dataSourceSim的数据源
    DataSourceContextHolder.setDBType("dataSouceSim");

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

  • 相关阅读:
    一些名词的解释
    开源代码从哪里获取
    Joomla软件及其类似物
    js常用随手记
    常用且难记的一些css
    阿里云ecs使用补充说明
    那些年踩过的坑之移动端
    一个题目引发的闭包、函数声明以及作用域的简单思考
    浅析toString()和toLocaleString()的区别
    由[]==![]说开去
  • 原文地址:https://www.cnblogs.com/JAYIT/p/12469535.html
Copyright © 2020-2023  润新知