本文主要讲解基于MybatisPlus开源框架组件Dynamic动态数据源切换

1、pom配置文件(这里仅展示动态数据源切换的核心依赖,具体jar包版本根据你的项目实际情况确定)


<!-- baomidou的动态数据源切换插件,版本最好与mybatisplus保持一致 -->
<dependency>   <groupId>com.baomidou</groupId>   <artifactId>dynamic-datasource-spring-boot-starter</artifactId>   <version>3.3.2</version> </dependency>
<!--Mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!--Mybatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
</dependency>

  

2、yaml文件配置

spring:
  autoconfigure:
    #自动化配置 例外处理
    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    dynamic:
      primary: mysql #默认数据源
      datasource:
        mysql:
          url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8
          username: root
          password: 123123
          driver-class-name: com.mysql.cj.jdbc.Driver
        oracle:
          url: jdbc:oracle:thin:@127.0.0.1:1521:xe
          username: system
          password: 123123
          driver-class-name: oracle.jdbc.OracleDriver
      druid:
        max-active: 50
        max-wait: 10000
        min-idle: 3
        initial-size: 5

mybatis-plus:
  mapper-locations: classpath:/mapper/*Mapper.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: cn.example.entity

以上两步完成,启动项目,项目如果启动成功,就代表数据源配置完成了

 

3、动态数据源切换

3.1、硬编码指定数据源

这种方式是通过插件提供的DS注解来实现的:com.baomidou.dynamic.datasource.annotation.DS,用例如下:

import cn.example.entity.Test;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

@DS("oracle")//可以使用在类上
@Repository
public interface TestMapper extends BaseMapper<Test> {

    List<String> queryDataGroups();

    List<String> queryDataTableNames();

    List<String> queryDataTypes();

    @DS("oracle")//也可以使用在方法上
    List<Map> sqlQuery(String queryContext);
}

  

3.2、动态指定数据源

第二种方式是请求时指定数据源,其实就是第一宗方式的变种,对于通过注解的方式,其内部实现原理也是在请求时通过AOP拦截到DS注解,然后设置当前请求的数据源的key,具体源码如下:

 

 而在执行时,是这么获取数据源的:

 

 这里看一下DynamicDataSourceContextHolder类内部结构:

 

 

通过源码我们可以发现,只要在执行SQL前调用DynamicDataSourceContextHolder设置当前需要使用的数据源,并且在使用后删除指定key就可以了,下面是我的代码demo

   public Object sqlQuery(String queryContext,String dataSource) {
        if (StringUtils.isBlank(queryContext))
            return null;
        DynamicDataSourceContextHolder.push(dataSource);
        try {
            queryContext = queryContext.trim();
            log.info("执行SQL:{}",queryContext);
            return testMapper.sqlQuery(queryContext);
        } catch (Exception e) {
            log.error("SQL执行错误:" + queryContext, e);
        } finally {
            DynamicDataSourceContextHolder.poll();
        }
        return null;
    }

 这种方式还需要提供数据源列表供接口调用方去选择,因此需要提供一个数据源列表查询功能,实际上看一下DynamicRoutingDataSource的内部实现就知道了,它其实维护了一个map来存储数据源,我们拿到这个map的所有key就可以了

 

 

 

 

 下面的我的代码demo

    @Autowired
    DynamicRoutingDataSource dynamicRoutingDataSource;

    @Override
    public Object dataSources() {
        Map<String, DataSource> currentDataSources = dynamicRoutingDataSource.getCurrentDataSources();
        return currentDataSources.keySet();
    }