方案_多数据源

比特寻梦说
• 阅读 896
有些应用一般会读写分离. 故对于程序而言涉及到多个数据源. 这里将多个数据源切换的功能做了下封装

实现

  1. 定义多个数据源 并分配一个 key 与之对应.
  2. 线程上下文存储当前 数据源的 key
  3. 实现 AbstractRoutingDataSource 重写 determineCurrentLookupKey 方法 为从线程上下文中取. 并注册到spring 容器
  4. 方便起见,定义一个注解 @DataSource 放在 mybatis mapper 方法签名上用于标识 用哪个数据源
  5. 新增 mybatis 插件(拦截器), 根据 @DataSource 动态指定所用数据源. 方法执行完ThreadLocal记得remove
  • 代码

// 初始化 多个数据源,并重写找 数据源 key 的方法为 从线程上下文中取
public class MultiRoutingDataSource extends AbstractRoutingDataSource {


    public MultiRoutingDataSource(Object defaultDataSource, Map<Object, Object> dataSources) {
        setDefaultTargetDataSource(defaultDataSource);
        Map<Object, Object> dses = Maps.newHashMap(MultiDsHolder.defaultDsKey, defaultDataSource);
        dses.putAll(dataSources);
        setTargetDataSources(dses);
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return MultiDsHolder.get();
    }

}

// 现在拦截器, 动态指定数据源
@Intercepts({
        @Signature(type = Executor.class, method = "update", args = {
                MappedStatement.class, Object.class}),
        @Signature(type = Executor.class, method = "query", args = {
                MappedStatement.class, Object.class, RowBounds.class,
                ResultHandler.class})})
public class MultiDsPlugin implements Interceptor {

    protected static final Logger logger = LoggerFactory.getLogger(MultiDsPlugin.class);


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        DataSource annotation = invocation.getMethod().getAnnotation(DataSource.class);
        if (annotation != null) {
            String key = annotation.value();
            MultiDsHolder.set(key);
        } else {
            //没配的话就用默认的
            MultiDsHolder.set(MultiDsHolder.defaultDsKey);
        }
        Object rst = null;
        try {
            rst = invocation.proceed();
        } catch (Exception e) {
            logger.error("mybatis 执行出错:", e);
        } finally {
            MultiDsHolder.remove();
        }
        return rst;
    }


    @Override
    public Object plugin(Object target) {
        if (target instanceof Executor) {
            return Plugin.wrap(target, this);
        } else {
            return target;
        }
    }

    @Override
    public void setProperties(Properties properties) {
        //
    }
}
点赞
收藏
评论区
推荐文章
我已经把它摸的透透的了!!!Spring 动态数据源设计实践,全面解析
Spring动态数据源动态数据源是什么?它能解决什么???在实际的开发中,同一个项目中使用多个数据源是很常见的场景。比如,一个读写分离的项目存在主数据源与读数据源。所谓动态数据源,就是通过Spring的一些配置来自动控制某段数据操作逻辑是走哪一个数据源。举个读写分离的例子,项目中引用了两个数据源,master、slave。通过Spring配置或扩展能力来
Wesley13 Wesley13
3年前
SSH实现动态数据源切换,事务场景下使用AOP
上周写代码遇到了切换数据源的问题,在同一个方法中向两个不同数据源做一些操作,但是这个方法使用了事务,所以网上一般动态切换数据源的方法就失效了。框架是spirngmvchibernate,数据库是oracle,连接池druid。一般情况下,操作数据都是在DAO层进行处理。一种办法是使用多个DataSource然后创建多个SessionFa
浩浩 浩浩
4年前
【Flutter实战】图片和Icon
3.5图片及ICON3.5.1图片Flutter中,我们可以通过Image组件来加载并显示图片,Image的数据源可以是asset、文件、内存以及网络。ImageProviderImageProvider是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvi
Chase620 Chase620
4年前
MyBatis 源码分析 - 内置数据源
MyBatis源码分析内置数据源1.简介本篇文章将向大家介绍MyBatis内置数据源的实现逻辑。搞懂这些数据源的实现,可使大家对数据源有更深入的认识。同时在配置这些数据源时,也会更清楚每种属性的意义和用途。因此,如果大家想知其然,也知其所以然。那么接下来就让我们一起去探索MyBatis内置数据源的源码吧。MyBatis支持三种数据源配置,分别
Stella981 Stella981
3年前
Spring Boot 集成 Mybatis 实现双数据源
这里用到了SpringBootMybatisDynamicDataSource配置动态双数据源,可以动态切换数据源实现数据库的读写分离。添加依赖加入Mybatis启动器,这里添加了Druid连接池、Oracle数据库驱动为例。<dependency<groupIdorg.mybatis.spring
Wesley13 Wesley13
3年前
Java IO输入输出
学前知道Java的IO使用“流”的概念来表示。IO流涉及到数据源和目的地。流,是从源“流向”目的的数据流。Java将各种数据源和目标之间数据的传输统一抽象为流,通过对流对象的操作来完成I/O功能。输入输出实际都是对内存而言的。数据源可以是键盘、文件、应用程序、鼠标、网络连接。
Stella981 Stella981
3年前
Spring Boot 2.x基础教程:使用JTA实现多数据源的事务管理
在一个SpringBoot项目中,连接多个数据源还是比较常见的。之前也介绍了如何在几种常用框架的场景下配置多数据源,具体可见:SpringBoot2.x基础教程:JdbcTemplate的多数据源配置(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fblog.didisp
Stella981 Stella981
3年前
Mybatis数据源结构解析之连接池
对于ORM框架而言,数据源的组织是一个非常重要的一部分,这直接影响到框架的性能问题。本文将通过对MyBatis框架的数据源结构进行详尽的分析,找出什么时候创建Connection,并且深入解析MyBatis的连接池。本章的组织结构:零、什么是连接池和线程池一、MyBatis数据源DataSo
Wesley13 Wesley13
3年前
3分钟搞定SpringBoot+Mybatis+druid多数据源和分布式事务
    在一些复杂的应用开发中,一个应用可能会涉及到连接多个数据源,所谓多数据源这里就定义为至少连接两个及以上的数据库了。    下面列举两种常用的场景:    一种是读写分离的数据源,例如一个读库和一个写库,读库负责各种查询操作,写库负责各种添加、修改、删除。    另一种是多个数据源之间并没有特别明显的操作,只是程序
多数据源管理:掌握@DS注解的威力 | 京东云技术团队
大家在日常后端开发过程,不可避免的会接触到需要用到配置多个数据源的场景,在这里,小编介绍一种简单方便的,只需要简单的配置和一个@DS注解就能实现动态数据源的方式,这种动态数据源底层原理是基于Mybatisplus来实现的。1、配置方式首先是pom.xmlc
SpringBoot 项目优雅实现读写分离 | 京东云技术团队
一、读写分离介绍当使用SpringBoot开发数据库应用时,读写分离是一种常见的优化策略。读写分离将读操作和写操作分别分配给不同的数据库实例,以提高系统的吞吐量和性能。读写分离实现主要是通过动态数据源功能实现的,动态数据源是一种通过在运行时动态切换数据库连
比特寻梦说
比特寻梦说
Lv1
想让每个平凡的日子里溢出欢喜。
文章
3
粉丝
0
获赞
0