[转]SpringMVC+ Mybatis 配置多数据源 + 手动切换数据源

正确可行的解决方法:使用Spring提供的AbstractRoutingDataSource类来根据请求路由到不同的数据源。具体做法是
先设置两个不同的dataSource代表不同的数据源,再建一个总的dynamicDataSource,根据不同的请求去设置dynamicDataSource。代码如下:

配置文件spring-mybatis.xml

<!--统一的dataSource-->
<bean id="dynamicDataSource" class="path.to.DynamicDataSource" >
    <property name="targetDataSources">
        <map key-type="java.lang.String">
            <!--通过不同的key决定用哪个dataSource-->
            <entry value-ref="dataSource" key="dataSource"></entry>
            <entry value-ref="mssqlDataSource" key="mssqlDataSource"></entry>
        </map>
    </property>
    <!--设置默认的dataSource-->
    <property name="defaultTargetDataSource" ref="dataSource">
    </property>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <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="initialSize" value="${jdbc.initialSize}"></property>
    <!-- 连接池最大数量 -->
    <property name="maxActive" value="${jdbc.maxActive}"></property>
    <!-- 连接池最大空闲 -->
    <property name="maxIdle" value="${jdbc.maxIdle}"></property>
    <!-- 连接池最小空闲 -->
    <property name="minIdle" value="${jdbc.minIdle}"></property>
    <!-- 获取连接最大等待时间 -->
    <property name="maxWait" value="${jdbc.maxWait}"></property>
</bean>

<!--电影票数据库是mssql2008,单独的数据库,配置如下-->
<bean id="mssqlDataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc-mssql.driver}" />
    <property name="url" value="${jdbc-mssql.url}" />
    <property name="username" value="${jdbc-mssql.username}" />
    <property name="password" value="${jdbc-mssql.password}" />
    <!-- 初始化连接大小 -->
    <property name="initialSize" value="${jdbc.initialSize}"></property>
    <!-- 连接池最大数量 -->
    <property name="maxActive" value="${jdbc.maxActive}"></property>
    <!-- 连接池最大空闲 -->
    <property name="maxIdle" value="${jdbc.maxIdle}"></property>
    <!-- 连接池最小空闲 -->
    <property name="minIdle" value="${jdbc.minIdle}"></property>
    <!-- 获取连接最大等待时间 -->
    <property name="maxWait" value="${jdbc.maxWait}"></property>
</bean>

<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dynamicDataSource" />
    <!-- 自动扫描mapping.xml文件 -->
    <property name="mapperLocations" value="classpath:path/to/mapping/*.xml"></property>
</bean>

<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="path.to.dao" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>

<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dynamicDataSource" />
</bean>

DynamicDataSource.java

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return CustomerContextHolder.getCustomerType();
    }
}

CustomerContextHolder.java

public class CustomerContextHolder {
    public static final String DATA_SOURCE_MYSQL = "dataSource";
    public static final String DATA_SOURCE_MSSQL = "mssqlDataSource";
    //用ThreadLocal来设置当前线程使用哪个dataSource
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
    public static void setCustomerType(String customerType) {
        contextHolder.set(customerType);
    }
    public static String getCustomerType() {
        String dataSource = contextHolder.get();
        if (StringUtils.isEmpty(dataSource)) {
            return DATA_SOURCE_MYSQL;
        }else {
            return dataSource;
        }
    }
    public static void clearCustomerType() {
        contextHolder.remove();
    }
}

ServiceImpl.java

CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MSSQL);

值得注意的是在CustomerContextHolder.java中使用了ThreadLocal类的set方法来设置当前线程要选择的dataSource,看一下set方法的源码:

ThreadLocal.set()

public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}

显而易见,获取当前线程,并且使用一个hashmap把需要存储的值设置进去。因为tomcat是用的线程池来处理每个请求,所以用ThreadLocal可以保证线程安全问题。同时这个AbstractRoutingDataSource类也值得好好研究一下。

总结

其实这个方案不仅仅可以用来处理不同数据源的问题,同时业务量上来之后需要把数据库进行主从分离或是把一个库分为多个库,都需要用到这样的做法。这次暴露的问题确实也了解了不少,继续学习吧!

原地址:http://www.cnblogs.com/puyangsky/p/6133553.html

亲测可用!

时间: 2024-12-05 07:06:55

[转]SpringMVC+ Mybatis 配置多数据源 + 手动切换数据源的相关文章

Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法(转)

一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基本上没有什么问题,但唯一可能出现问题的就是在hibernate做添加操作生成主键策略的时候.因为我们都知道hibernate的数据库本地方言会针对不同的数据库采用不同的主键生成策略. 所以针对这一问题不得不采用自定义的主键生成策略,自己写一个主键生成器的表来维护主键生成方式或以及使用其他的方式来生成

【转】一次SpringMVC+ Mybatis 配置多数据源经历

需求 现在在维护的是学校的一款信息服务APP的后台,最近要开发一些新功能,其中一个就是加入学校电影院的在线购票.在线购票实际上已经有一套系统了,但是是外包给别人开发的,我们拿不到代码只能拿到数据库,并且也不一定能很好的兼容之前的代码,所以需要基于这个数据库来进行新的开发. 现在用的后台是SpringMVC+Mybatis+MySQL开发的,购票用的是SQL Server 2008(好古老的东西了),因为要用一套用户体系所以不可能再去单独为了这个功能弄一个系统出来,因此要在原项目中兼容这个数据库.

springmvc+mybatis配置

环境: Jdk 1.8.0_40 Eclipse 4.4.2 Tomcat 8.0.20 Maven 3.2.5 Mybatis 3.2.8 Spring 4.1.5 主要步骤:(以下能够正常运行) 1. 新建工程 Maven Project -> New Maven Project 保持默认,直接下一步 -> 选择org.apache.maven.archetypes,点击下一步 -> 输入Group id 和Artifact id,完成 2. 配置pom.xml <projec

springboot添加多数据源 以及 动态添加数据源动态切换数据源

<!-- Druid 数据连接池依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.6</version> </dependency> //指定使用Druid做数据源spring.datasource.type=com.alibaba.druid.pool.Dru

springMVC,mybatis配置事务

首先应该对context:include-filter和context:exclude-filter有一个了解,include是包含这个,而不是只包含,下面会有例子看看: 这是我最开始配置的MVC的配置文件,我以为是我这么配置以后,这个扫描就会只扫描Controller注解,但是不是这样的,按照我的测试 这个注解是包含了Controller,但是也应该也是对Service注解进行了扫描的,否则事务不应该不好使: 下面来看我的成功的配置文件: 在这个配置文件中仅仅是将Service剔除掉了而已,这

Springmvc+mybatis配置前台页面传递JSON串给后台接收。

前台页面js方法: $(document).ready(function(){ var saveDataAry=[]; var data1={"id":5,"name":"益生元","province":"西藏"}; var data2={"id":6,"name":"好爸爸","province":"拉萨"

spring自动识别数据库并切换数据源

一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基本上没有什么问题,但唯一可能出现问题的就是在hibernate做添加操作生成主键策略的时候.因为我们都知道hibernate的数据库本地方言会针对不同的数据库采用不同的主键生成策略. 所以针对这一问题不得不采用自定义的主键生成策略,自己写一个主键生成器的表来维护主键生成方式或以及使用其他的方式来生成

如何玩转最新的项目的搭配springmvc+mybatis+Redis+Nginx+tomcat+mysql

上一次完成nginx+tomcat组合搭配,今天我们就说说,这几个软件在项目中充当的角色: 要想完成这几个软件的组合,我们必须知道和熟悉应用这个框架, 一: Nginx:在项目中大多数作为反向代理服务器.其目的处理http静态页面.和分发请求给tomcat.是目前处理大量请求的解决方案. tomcat:作为处理动态页面的服务器.由Ngxin 均衡分给的请求来处理. redis:在这个里redis 处理两个重要的功能:第一,nginx分发请求给tomcat.如何保持session的同步.就是利用r

spring+springMVC+Mybatis架构下采用AbstractRoutingDataSource、atomikos、JTA实现多数据源灵活切换以及分布式事务管理

背景: 1.系统采用SSM架构.需要在10多个MYSQL数据库之间进行切换并对数据进行操作,上篇博文<springMVC+Mybatis(使用AbstractRoutingDataSource实现多数据源切换时)事务管理未生效的解决办法> 2.第一步先通过AbstractRoutingDataSource实现了多数据源的灵活切换,但是后来发现事务不起作用: 3.发现问题是因为重复扫描service包导致第二次扫入容器的BEAN没有纳入事务管理,因此在springMVC的配置文件中排除了对Ser