2019独角兽企业重金招聘Python工程师标准>>>

1、核心思想,spring提供了一个DataSource的子类,该类支持多个数据源

org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource

该类的源码如下:

org.springframework.jdbc.datasource.lookup;java.sql.Connection;
java.sql.SQLException;
java.util.HashMap;
java.util.Iterator;
java.util.Map;
java.util.Map.Entry;
javax.sql.DataSource;
org.springframework.beans.factory.InitializingBean;
org.springframework.jdbc.datasource.AbstractDataSource;
org.springframework.jdbc.datasource.lookup.DataSourceLookup;
org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
org.springframework.util.Assert;AbstractRoutingDataSource AbstractDataSource InitializingBean {// 注意这里,这里使用Map存放多个数据源Map<Object, Object> targetDataSources;... // 篇幅有限,省略其他代码,有兴趣的同学可以自行研究,还是支持蛮多功能的,比如JNDI等数据源方式     // 注意这个暴露的方法,spring在从数据源中获取数据库连接时,通过这个方法确定数据源DataSource determineTargetDataSource() {Assert.notNull(.resolvedDataSources, );Object lookupKey = .determineCurrentLookupKey();DataSource dataSource = (DataSource).resolvedDataSources.get(lookupKey);(dataSource == && (.lenientFallback || lookupKey == )) {dataSource = .resolvedDefaultDataSource;}(dataSource == ) {IllegalStateException(+ lookupKey + );} {dataSource;}}// 对外暴露的决定数据源的方法,通过外部设置数据源的key值,// spring自行从已存储的数据源中查找指定数据源Object determineCurrentLookupKey();
}

通过分析源码,可以知道我们只需要实现如何动态设置切换数据源的方式即可,可以考虑使用注解的方式在指定的位置添加数据源注解,利用AOP动态指定数据源。

自定义的数据源如下:

com.yao.yz.yaowangdrug.dataSource;org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;DynamicDataSource AbstractRoutingDataSource{Object determineCurrentLookupKey() {DataSourceHolder.();}
}

2、自定义注解,本章节不做过多解释,对于注解有兴趣的同学请自行研究,废话一句:程序员以实际应用为主,研究行的内容请自行学习

com.yao.yz.yaowangdrug.dataSource;java.lang.annotation.*;(RetentionPolicy.)
(ElementType.)
@{String value();
}

3、定义一个数据源切换功能组件,其中数据源存放的方式采用ThreadLocal的形式,我是单独把存放做成一个额外的组件,这个是可以自行决定的,代码如下:

com.yao.yz.yaowangdrug.dataSource;DataSourceHolder {ThreadLocal<String> = InheritableThreadLocal<String>();setDataSourceKey(String dataSource) {.set(dataSource);}Object getDataSourceKey() {.get();}}
com.yao.yz.yaowangdrug.dataSource;org.apache.log4j.Logger;
org.aspectj.lang.JoinPoint;
org.aspectj.lang.reflect.MethodSignature;java.lang.reflect.Method;DynamicAspect {Logger = Logger.(DynamicAspect.);switchDataSource(JoinPoint point) NoSuchMethodException{Object target = point.getTarget();String method = point.getSignature().getName();Class<?>[] classz = target.getClass().getInterfaces();Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()).getMethod().getParameterTypes();Method m = classz[].getMethod(method, parameterTypes);(m != && m.isAnnotationPresent(.)) {data = m.getAnnotation(.);DataSourceHolder.(data.value());}.info(+ DataSourceHolder.());}}

4、在spring配置文件添加多个数据源,并将多个数据源统一纳入自定义数据源的管理,具体的配置信息如下:

<!--装载配置文件,将数据源的配置做成配置文件,方便管理,有兴趣的同学自行参考--><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="location" value="Config.properties"/></bean>

<!--数据源1--><bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver" /><property name="jdbcUrl" value="${dataSource1.jdbc.url}" /><property name="user" value="${dataSource1.jdbc.username}" /><property name="password" value="${dataSource1.jdbc.password}" /><property name="minPoolSize" value="${dataSource1.jdbc.minPoolSize}" /><property name="maxPoolSize" value="${dataSource1.jdbc.maxPoolSize}" /></bean>

<!--数据源2--><bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver" /><property name="jdbcUrl" value="${dataSource2.jdbc.url}" /><property name="user" value="${dataSource2.jdbc.username}" /><property name="password" value="${dataSource2.jdbc.password}" /><property name="minPoolSize" value="${dataSource2.jdbc.minPoolSize}" /><property name="maxPoolSize" value="${dataSource2.jdbc.maxPoolSize}" /></bean>

<!--自定义数据源,将所有的数据源纳入自定义数据源管理--><bean id="dataSource" class="com.yao.yz.yaowangdrug.dataSource.DynamicDataSource"><property name="targetDataSources"><map>          <!-- 对应spring提供的AbstractRoutingDataSource的Map --><entry key="dataSource1" value-ref="dataSource1"/><entry key="dataSource2" value-ref="dataSource2"/></map></property><property name="defaultTargetDataSource" ref="dataSource1"/></bean>

5、配置数据源切换的AOP,代码如下:

<!--动态决定数据源--><bean id="dataSourceSwitchAspect" class="com.yao.yz.yaowangdrug.dataSource.DynamicAspect"/><aop:config><aop:aspect id="dynamicAspect" ref="dataSourceSwitchAspect"><!--数据源切换可以控制为Dao或者service层,请根据实际业务需要自行决定-->      <aop:pointcut id="dynamicPointCut" expression="execution(* com.xx.xx.xx.dao.*.*(..))"/><aop:before method="switchDataSource" pointcut-ref="dynamicPointCut"/></aop:aspect></aop:config>

6、使用spring整合mybatis,和一般的整合却别在于使用的数据源为自定义数据源,代码如下:

   classpath:ModelMapper.xmlclasspath:ModelMapper1.xmlclasspath:ModelMapper2.xml

注意:目前精力有限,此处为什么可以使用自定义多个数据源的底层原理还没来得及看,有兴趣的同学请自行研究,如果好心的话可以简单的告知我,谢谢你了~~~

7、将自定义数据源纳入spring的事务管理器管理,配置代码如下:

<!--事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!--申明事务回滚的方法和异常信息--><tx:advice id="txAdvic" transaction-manager="transactionManager"><tx:attributes><tx:method name="do*" read-only="false" propagation="REQUIRED" rollback-for="java.lang.Exception"/></tx:attributes></tx:advice><!--申明事务范围--><aop:config><aop:pointcut id="txPointCut" expression="execution(* com.xx.xx.xx.service.*.*(..))"/><aop:advisor advice-ref="txAdvic" pointcut-ref="txPointCut"/></aop:config>

Model类:

com.yao.yz.yaowangdrug.model;DBModel {String ;String ;String getValue() {;}setValue(String value) {.= value;}String getKey() {;}setKey(String key) {.= key;}
}

Dao接口:

com.yao.yz.yaowangdrug.dao;;
com.yao.yz.yaowangdrug.model.DBModel;DBDao {()insert(DBModel dbModel) Exception;}

Service接口:

com.yao.yz.yaowangdrug.service;com.yao.yz.yaowangdrug.model.DBModel;
;DBService {doInsert() Exception;doUpdate() Exception;testSeperateDB() Exception;}

关于事务的控制,有一下几点说明:

1、采用申明或者注解实现事务控制时时,因为开启了事务控制,所以如果是两个不同的数据源Dao,根据spring的事务传播特性,第二个事务开启将使用已有的事务(即将采用第一个数据源的数据库连接)进行事务操作,所以此时事务控制是失效的(即使切面执行了数据源切换)。结论就是跨数据库的事务是无法通过spring的数据库控制实现的!!!请切记。

2、同一个数据源的事务控制和普通的数据源控制是一致的,没有什么区别。

以上代码都是经过测试通过,可以实现跨库的数据方式,主要的应用场景是mysql的数据库读写分离。如果不正确的地方请告知,谢谢!

转载于:https://my.oschina.net/u/1471781/blog/508906

spring + mybatis + 多数据源整合事务相关推荐

  1. spring+mybatis 多数据源整合

    直接看spring的配置吧 <!-- 数据源配置 -->   <bean id="ds1" class="org.apache.commons.dbcp ...

  2. spring+mybatis 多数据源切换

    spring+mybatis 多数据源切换 摘自: http://www.oschina.net/code/snippet_347813_12525 1. 代码: DbContextHolder pu ...

  3. spring mybatis 多数据源配置 jeesite 多数据源配置

    spring mybatis 多数据源配置 jeesite 多数据源配置 一.情景描述 在系统数据达到一定的访问量时,遇到单个数据库瓶颈,所以需要扩展数据库,启用第二个数据源资源,项目架构变成 一个服 ...

  4. Spring+SpringMVC+Mybatis 多数据源整合

    原文地址:http://blog.csdn.net/q908555281/article/details/50316137 ----------------------------------- 此篇 ...

  5. Spring+Mybatis多数据源配置(一)——MySQL与Oracle通过配置切换

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  6. springmvc整合mysql_SpringMVC+Spring+Mybatis+Maven+mysql整合

    一.准备工作 1.工具:jdk1.7.0_80(64)+tomcat7.0.68+myeclipse10.6+mysql-5.5.48-win32 2. 开发环境安装配置.Maven项目创建(参考:h ...

  7. spring事务隔离级别、传播行为以及spring+mybatis+atomikos实现分布式事务管理

    1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单 ...

  8. spring+mybatis之声明式事务管理初识(小实例)

    前几篇的文章都只是初步学习spring和mybatis框架,所写的实例也都非常简单,所进行的数据访问控制也都很简单,没有加入事务管理.这篇文章将初步接触事务管理. 1.事务管理 理解事务管理之前,先通 ...

  9. Spring+Mybatis 多数据源配置

    2013-03-14  项目目录结构如下: spring配置文件 Xml代码  <?xml version="1.0" encoding="UTF-8"? ...

  10. Spring+Mybatis多数据源配置(四)——AbstractRoutingDataSource实现数据源动态切换

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

最新文章

  1. ​【安全牛学习笔记】WPS及其他工具WPS
  2. Sizeof与Strlen的区别与联系(转)
  3. 物联网:从源头为生产环境安全把关
  4. Android Studio的git功能的使用
  5. 多级菜单栏展开隐藏动画
  6. pip错误:TypeError: parse() got an unexpected keyword argument 'transport_encoding'
  7. IntellIJ IDEA 启动 参数 配置
  8. Java读书笔记(4)-多线程(二)
  9. MFC SendMessage()函数传递字符串
  10. 字符串池化,减少了三分之一的内存占用
  11. (第2篇)一篇文章教你轻松安装hadoop
  12. 谁顶住双11的世界级流量洪峰?神龙架构负责人等9位大牛现场拆解阿里秘籍
  13. einops.rearrange、repeat、reduce==>对维度进行操作
  14. HTTP的请求与响应问题(没有了CSDN,暂时把这里当作论坛了)
  15. git 安装_Windows系统Git安装教程(详解Git安装过程)
  16. 团队管理心得--建团队,管事理人
  17. w ndows7旗舰版网卡驱动,windows7万能网卡驱动官方下载
  18. 关于“缓存着色(cache coloring, page coloring)”技术的相关资料介绍
  19. 10分钟入门Pandas(添加一些个人见解)
  20. 中国区域地面气象要素驱动数据集(1979-2018)数据下载与处理

热门文章

  1. 四川师范大学计算机科学学院官网,四川师范大学
  2. 老显卡都涨价了,所以我把坏的显卡拿出来修
  3. No package ‘glib-2.0‘ found/No package ‘gobject-2.0‘ found
  4. C语言中用二进制输出一个数字
  5. MAC编译jogl/gluegen很顺利
  6. 软件基本功:代码要有道理
  7. LINUX给机器改名
  8. 640x360,H264 SPS头如何表示高度?
  9. 软件一定要联网安装,只有内网就干瞪眼
  10. 管理感悟:可接受的不参加培训的理由