1.CustomerContextHolder 数据源管理类,负责管理当前的多个数据源,基于ThreadLocal实现,对每个线程设置不同的目标数据源

public class CustomerContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setCustomerType(String customerType) {
contextHolder.set(customerType);
} public static void clearCustomerType() {
contextHolder.remove();
} public static String getCustomerType() {
return contextHolder.get();
}
}

2.DynamicDataSource 数据注入类

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

3.配置文件

  a)spring-context-data-source.xml

  

<!--统一的dataSource -->
<bean id="dataSource" class="com.thinkgem.jeesite.common.config.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="a" key="a"></entry>
<entry value-ref="b" key="b"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="a">
</property>
</bean> <!-- 数据源配置, 使用 BoneCP 数据库连接池 -->
<bean id="a" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}" />
<property name="minIdle" value="${jdbc.pool.minIdle}" />
<property name="maxActive" value="${jdbc.pool.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="${jdbc.testSql}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用) <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean> <!-- 数据源配置, 使用 BoneCP 数据库连接池 -->
<bean id="b" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url.kpidata}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}" />
<property name="minIdle" value="${jdbc.pool.minIdle}" />
<property name="maxActive" value="${jdbc.pool.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="${jdbc.testSql}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用) <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean>

  b)spring-context.xml mybatis的配置

<!-- MyBatis begin -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:/mappings/**/*.xml"/>
<property name="configLocation" value="classpath:/mybatis-config.xml"></property>
</bean> <!-- 扫描basePackage下所有以@MyBatisDao注解的接口 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<property name="basePackage" value="com.thinkgem.jeesite"/>
<property name="annotationClass" value="com.thinkgem.jeesite.common.persistence.annotation.MyBatisDao"/>
</bean>

4.使用

  @ResponseBody
@RequestMapping(value = "jeesiteDb")
public Map<String, Object> jeesiteDb() {
Map<String, Object> returnMap = new HashMap<String, Object>();
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_JEESITE);
List<Map<String, String>> list = testService.queryJeesite();
returnMap.put("data", list);
return returnMap;
} @ResponseBody
@RequestMapping(value = "myTestDb")
public Map<String, Object> myTestDb() {
Map<String, Object> returnMap = new HashMap<String, Object>();
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MT_TEST);
List<Map<String, String>> list = testService.queryMyTest();
returnMap.put("data", list);
return returnMap;
}

5.问题

a) 请求数据源的方法一定要写在controller中,不要写在dao中

CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MT_TEST);

b) 如果是同一个controller中,不同方法请求不同的数据源,上面的写法足够了,但是如果要统一个方法动态指定数据源,那么需要在使用之后加上,清除当前线程的数据源,否则数据切换会失败

CustomerContextHolder.clearCustomerType();

Spring MVC+Mybatis 多数据源配置及发现的几个问题的更多相关文章

  1. Spring MVC+Mybatis 多数据源配置

    文章来自:https://www.jianshu.com/p/fddcc1a6b2d8 1. 继承AbstractRoutingDataSource AbstractRoutingDataSource ...

  2. spring mvc+mybatis+多数据源切换

    spring mvc+mybatis+多数据源切换,选取oracle,mysql作为例子切换数据源.oracle为默认数据源,在测试的action中,进行mysql和oracle的动态切换. web. ...

  3. spring, spring mvc, mybatis整合文件配置详解

    转自:http://www.cnblogs.com/wxisme/p/4924561.html 使用SSM框架做了几个小项目了,感觉还不错是时候总结一下了.先总结一下SSM整合的文件配置.其实具体的用 ...

  4. spring boot mybatis 多数据源配置

    package com.xynet.statistics.config.dataresources; import org.springframework.jdbc.datasource.lookup ...

  5. spring boot Mybatis多数据源配置

    关于 有时候,随着业务的发展,项目关联的数据来源会变得越来越复杂,使用的数据库会比较分散,这个时候就会采用多数据源的方式来获取数据.另外,多数据源也有其他好处,例如分布式数据库的读写分离,集成多种数据 ...

  6. Spring Boot + Mybatis 多数据源配置实现读写分离

    本文来自网易云社区 作者:王超 应用场景:项目中有一些报表统计与查询功能,对数据实时性要求不高,因此考虑对报表的统计与查询去操作slave db,减少对master的压力. 根据网上多份资料测试发现总 ...

  7. Spring MVC 使用tomcat中配置的数据源

    Spring MVC 使用tomcat中配置的数据源 配置tomcat数据源 打开tomcat目录下的conf目录,编辑sever.xml目录.在<GlobalNamingResources&g ...

  8. Spring Boot 2.X(五):MyBatis 多数据源配置

    前言 MyBatis 多数据源配置,最近在项目建设中,需要在原有系统上扩展一个新的业务模块,特意将数据库分库,以便减少复杂度.本文直接以简单的代码示例,如何对 MyBatis 多数据源配置. 准备 创 ...

  9. Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合(注解及源码)

    Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合(注解及源码) 备注: 之前在Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合中 ...

随机推荐

  1. TDH-ssh免密登录

    [root@tw-node118 ~]# ssh-keygen -t rsa -P '' 这个指令会在/root/.ssh下生成id_rsa和id_rsa.pub文件.看一下/root/.ssh下的文 ...

  2. ruby Iconv.iconv编码方法

    #定义一个UTF-8=>GBK的方法def encoding inStr    Iconv.iconv("GBK","UTF-8",inStr)end#定 ...

  3. Vmware Player 比较

    .wiz-todo, .wiz-todo-img {width: 16px; height: 16px; cursor: default; padding: 0 10px 0 2px; vertica ...

  4. malloc/free函数

    一.malloc 函数原型:void *malloc(unsigned int size); 功       能:在内存的动态存储区中分配一个长度为size的连续空间. 返  回 值:指向所分配的连续 ...

  5. Windows Azure 配置Active Directory 主机(2)

    前一篇概况给大家介绍了,在云端部署一台DC 需要满足一些条件,接下来进入正题,云端VM安装域控制器具体步骤. 步骤1 :验证 主DC 的静态 IP 地址 1.登录到 Corp 网络上的 主DC. 2. ...

  6. 使用Python+selenium过程中所需安装的库和软件

    一.下载地址: 1.setuptools:https://pypi.python.org/pypi/setuptools#downloads 中file对应的后缀为zip的软件 pip:https:/ ...

  7. javascript 和Jquery 互转

    jQuery对象转成DOM对象: 两种转换方式将一个jQuery对象转换成DOM对象:[index]和.get(index); (1)jQuery对象是一个数据对象,可以通过[index]的方法,来得 ...

  8. javase基础-Helloword

    public class HelloWorld {//创建一个类 :1.类名首字母需要大写:2.类名必须和文件名一致         public static void main(String[]  ...

  9. LibreOJ #515. 「LibreOJ β Round #2」贪心只能过样例

    题目描述 一共有 nnn个数,第 iii 个数 xix_ix​i​​ 可以取 [ai,bi][a_i , b_i][a​i​​,b​i​​] 中任意值.设 S=∑xi2S = \sum{{x_i}^2 ...

  10. java面试题(杨晓峰)---第七讲谈谈int和integer有什么区别?

    理解装箱和拆箱的过程. 对象由三部分组成:对象头,对象实例,对齐填充. 对象头:一般是十六个字节,分两部分,第一部分:哈希码,锁状态标志,线程持有的锁,偏向线程id,gc分代年龄等,第二部分是类型指针 ...