springboot+mybatis实现动态切换数据源

前几天有个需求,需要使用不同的数据源,例如某业务要用A数据源,另一个业务要用B数据源。我上网收集了一些资料整合了一下,虽然最后这个需求不了了之了,但是多数据源动态切换还是蛮好用的,所以记录一下,或许以后有用呢?或者自己感兴趣又想玩呢!

1.加个依赖

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>       <version>1.3.1</version>
        </dependency>

2.application.properties配置文件

#主从数据库
master.db.driverClassName=com.mysql.jdbc.Driver
master.db.url=jdbc:mysql://localhost:3306/cbd?characterEncoding=UTF-8&useUnicode=true&useSSL=false
master.db.username=root
master.db.password=admin
slave.db.driverClassName=com.mysql.jdbc.Driver
slave.db.url=jdbc:mysql://localhost:3306/cbd_test?characterEncoding=UTF-8&useUnicode=true&useSSL=false
slave.db.username=root
slave.db.password=admin

mybatis.config-location= classpath:config/mybatis-config.xml
mybatis.mapper-locations=classpath:mapper/**/*.xml

3.禁用springboot默认加载数据源配置

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

4.数据源配置类

/**
 * 主数据源
 */
@Configuration
@ConfigurationProperties(prefix = "master.db")
public class MasterDataSourceConfig {
    private String url;
    private String username;
    private String password;
    private String driverClassName;
}
/**
 * 从数据源配置
 */
@Configuration
@ConfigurationProperties(prefix = "slave.db")
public class SlaveDataSourceConfig {
    private String url;
    private String username;
    private String password;
    private String driverClassName;
}
/**
 * 数据源配置类
 */
@Configuration
public class DataSourceComponent {

    @Resource
    private MasterDataSourceConfig masterDataSourceConfig;

    @Resource
    private SlaveDataSourceConfig slaveDataSourceConfig;

     @Bean(name = "master")
    public DataSource masterDataSource() {
        DataSource dataSource = new DataSource();
        dataSource.setUrl(masterDataSourceConfig.getUrl());
        dataSource.setUsername(masterDataSourceConfig.getUsername());
        dataSource.setPassword(masterDataSourceConfig.getPassword());
        dataSource.setDriverClassName(masterDataSourceConfig.getDriverClassName());
        return dataSource;
    }

    @Bean(name = "slave")
    public DataSource slaveDataSource() {
        DataSource dataSource = new DataSource();
        dataSource.setUrl(slaveDataSourceConfig.getUrl());
        dataSource.setUsername(slaveDataSourceConfig.getUsername());
        dataSource.setPassword(slaveDataSourceConfig.getPassword());
        dataSource.setDriverClassName(slaveDataSourceConfig.getDriverClassName());
        return dataSource;
    }

    @Primary//不加这个会报错。
    @Bean(name = "multiDataSource")
    public MultiRouteDataSource exampleRouteDataSource() {
        MultiRouteDataSource multiDataSource = new MultiRouteDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("master", masterDataSource());
        targetDataSources.put("slave", slaveDataSource());
        multiDataSource.setTargetDataSources(targetDataSources);
        multiDataSource.setDefaultTargetDataSource(masterDataSource());
        return multiDataSource;
    }
}

5.数据源上下文

/**
 * 数据源上下文
 */
public class DataSourceContext {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    public static void setDataSource(String value) {
        contextHolder.set(value);
    }

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

    public static void clearDataSource() {
        contextHolder.remove();
    }
}

6.DataSource路由类

/*
*    重写的函数决定了最后选择的DataSource
*/
public class MultiRouteDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        //通过绑定线程的数据源上下文实现多数据源的动态切换,有兴趣的可以去查阅资料或源码
        return DataSourceContext.getDataSource();
    }

}

7.使用,修改上下文中的数据源就可以切换自己想要使用的数据源了。

    public UserVO findUser(String username) {
        DataSourceContext.setDataSource("slave");
        UserVO userVO = userMapper.findByVO(username);
        System.out.println(userVO.getName()+"=====================");
        return null;
    }

这种是在业务中使用代码设置数据源的方式,也可以使用AOP+注解的方式实现控制,方法多多!

原文地址:https://www.cnblogs.com/tinyj/p/9864128.html

时间: 2024-11-04 00:12:59

springboot+mybatis实现动态切换数据源的相关文章

Spring + Mybatis 项目实现动态切换数据源

项目背景:项目开发中数据库使用了读写分离,所有查询语句走从库,除此之外走主库. 最简单的办法其实就是建两个包,把之前数据源那一套配置copy一份,指向另外的包,但是这样扩展很有限,所有采用下面的办法. 参考了两篇文章如下: http://blog.csdn.net/zl3450341/article/details/20150687 http://www.blogjava.net/hoojo/archive/2013/10/22/405488.html 这两篇文章都对原理进行了分析,下面只写自己

基于spring+mybatis+atomikos+jta实现分布式事务(2)-动态切换数据源

本文介绍基于spring+mybatis+atomikos+jta实现分布式事务,由程序动态切换数据源,通过atomikos可实现分布式事务一致性. 版本:spring-3.2.9.RELEASE.mybatis-3.4.4.atomikos-4.0.5.jdk1.8 1,maven配置文件pom.xml如下: <!-- test --> <dependency> <groupId>junit</groupId> <artifactId>juni

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

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

springboot+mybatis+Druid配置多数据源(mysql+postgre)

springboot+mybatis+Druid配置多数据源(mysql+postgre)引入pom依赖设置application多数据源config配置db1config配置(主数据库配置)db2config配置(其他数据库)事务处理mapper层 springboot+mybatis+Druid配置多数据源(mysql+postgre) 参考资料: 第八章 springboot + mybatis + 多数据源 springboot + mybatis + druid + 多数据源 spri

hibernate动态切换数据源

起因: 公司的当前产品,主要是两个项目集成的,一个是java项目,还有一个是php项目,两个项目用的是不同的数据源,但都是mysql数据库,因为java这边的开发工作已经基本完成了,而php那边任务还很多,人手也比较紧,产品上线日期紧促,所以领导希望java这边能够帮助php那边写接口,所以需要切换数据源 思路: 动态切换数据源确切的来说是在同一类型数据库的情况下的.意思就是说 , 在系统中的使用的数据库分布在多台数据库服务器或者在同台服务器上的多个数据库. 在运行时期间根据某种标识符来动态的选

AOP获取方法注解实现动态切换数据源

(其中@Order(1)作用: Spring中的事务是通过aop来实现的,当我们自己写aop拦截的时候,会遇到跟spring的事务aop执行的先后顺序问题,比如说动态切换数据源的问题,如果事务在前,数据源切换在后,会导致数据源切换失效,所以就用到了Order(排序)这个关键字.) @Order(1) @Aspect @Repository public class DataSourceAspect { @Pointcut("execution(* com.xxx.service.impl.*.*

mybatis动态切换数据源

(#)背景:由于业务的需求,导致需要随时切换15个数据源,此时不能low逼的去写十几个mapper,所以想到了实现一个数据源的动态切换 首先要想重写多数据源,那么你应该理解数据源的一个概念是什么,DataSourceTransactionManager这个类就是spring中对于数据源的封装,其中DataSource做为 他的一个成员.接下来我们要介绍一下我们切换动态数据源需要使用的类,AbstractRoutingDataSource,先来看看这个类的源码 首先看看这几个变量,targetDa

Spring MVC动态切换数据源(多数据库类型)

最近由于项目需求,需要将Sql Server 和 Mysql 两种数据库整合到一个项目,项目的用到的框架是SSM. 因此尝试了利用AOP切面来切每次执行的Servcie方法,根据Service所在的包名来实现数据源自动切换. 1.项目架构如下: 2.在com.jiefupay.database包中建立四个类: 其中 DataSourceContextHolder.java类源码如下: package com.jiefupay.datebase; public class DataSourceCo

SpringBoot运行时动态添加数据源

此方案适用于解决springboot项目运行时动态添加数据源,非静态切换多数据源!!! 一.多数据源应用场景: 1.配置文件配置多数据源,如默认数据源:master,数据源1:salve1...,运行时动态切换已配置的数据源(master.salve1互相切换),无法在运行时动态添加配置文件中未配置的数据源. 2.配置一个默认数据源,运行时动态添加新数据源使用(本博客适用于此场景) 二.解决方案: Spring提供了AbstractRoutingDataSource用于动态路由数据源,第一种场景