MybatisPlus配置双数据库驱动

2023-11-01

个人博客纯净版

MybatisPlus配置双数据库驱动 | 代码搬运工

最近项目中需要用到2种数据库驱动连接数据库,下面我们基于MybatisPlus实现一下

具体实现

1、在pom.xml中添加如下依赖:

<properties>
    <java.version>1.8</java.version>
    <lombok.version>1.18.2</lombok.version>
    <mybatis-plus.version>3.2.0</mybatis-plus.version>
    <druid.version>1.1.9</druid.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- postgrepsql-->
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>${mybatis-plus.version}</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus</artifactId>
        <version>${mybatis-plus.version}</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>${druid.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
</dependencies>

2、在yml配置文件中添加如下配置:

server:
  port: 8080

spring:
  application:
    name: xxxx
  datasource:
    druid:
      # mysql数据源配置
      db1:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/db1?useUnicode=true&characterEncoding=UTF-8&useSSL=false
        username: ${username}
        password: ${password}
        initial-size: 5
        min-idle: 5
        max-active: 50
      # postgresql 数据源配置
      db2:
        driver-class-name: org.postgresql.Driver
        url: jdbc:postgresql://127.0.0.1:5432/db2?useUnicode=true&characterEncoding=utf-8
        username: ${username}
        password: ${password}
        initial-size: 5
        min-idle: 5
        max-active: 50

# mybatis-plus配置
mybatis-plus:
  type-aliases-package: com.dms.gateway.api.entity
  mapper-locations: classpath:/mapper/*Mapper.xml
  global-config:
    db-config:
      id-type: auto
      field-strategy: not_empty
      logic-delete-value: 1
      logic-not-delete-value: 0
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
    call-setters-on-nulls: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

3、新建DataSourceEnum枚举类,如下:

public enum DataSourceEnum {

    DB1("db1"),
    DB2("db2");

    private String value;

    DataSourceEnum(String value){this.value=value;}

    public String getValue() {
        return value;
    }
}

4、新建DataSourceContextHolder类,如下:

public class DataSourceContextHolder {

    // 默认数据源
    public static final String DEFAULT_DS = DataSourceEnum.DB1.getValue();

    private static final ThreadLocal<String> contextHolder = new InheritableThreadLocal<>();

    /**
     *  设置数据源
     * @param db
     */
    public static void setDataSource(String db){
        contextHolder.set(db);
    }

    /**
     * 取得当前数据源
     * @return
     */
    public static String getDataSource(){
        return contextHolder.get();
    }

    /**
     * 清除上下文数据
     */
    public static void clear(){
        contextHolder.remove();
    }
}

5、新建MultipleDataSource类,如下:

public class MultipleDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSource();
    }
}

5、新建DataSource注解,如下:

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {

    DataSourceEnum value() default DataSourceEnum.DB1;
}

6、新建面向类和方法级别的切面,如下:

@Component
@Slf4j
@Aspect
@Order(-6)
public class DataSourceClassAspect {


    @Before("@within(dataSource)")
    public void doBefore(JoinPoint point, DataSource dataSource){
        log.info("切换到数据源[{}]", dataSource.value().getValue());
        DataSourceContextHolder.setDataSource(dataSource.value().getValue());
    }

    @After("@within(dataSource)")
    public void doAfter(JoinPoint point, DataSource dataSource){
        log.info("回收数据源[{}]", dataSource.value().getValue());
        DataSourceContextHolder.clear();
    }
}
@Component
@Slf4j
@Aspect
@Order(-5)
public class DataSourceMethodAspect {


    @Before("@annotation(dataSource)")
    public void doBefore(JoinPoint point, DataSource dataSource){
        log.info("切换到数据源[{}]", dataSource.value().getValue());
        DataSourceContextHolder.setDataSource(dataSource.value().getValue());
    }

    @After("@annotation(dataSource)")
    public void doAfter(JoinPoint point, DataSource dataSource){
        log.info("回收数据源[{}]", dataSource.value().getValue());
        DataSourceContextHolder.clear();
    }
}

7、新建多数据源配置类,如下:

@Configuration
@MapperScan("com.dms.gateway.api.mapper")
public class MybatisPlusConfig {

    /*
     * 分页插件,自动识别数据库类型
     * 多租户,请参考官网【插件扩展】
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        return paginationInterceptor;
    }

    @Bean(name = "db1")
    @ConfigurationProperties(prefix = "spring.datasource.druid.db1" )
    public DataSource db1() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.druid.db2" )
    public DataSource db2() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 动态数据源配置
     * @return
     */
    @Bean
    @Primary
    public DataSource multipleDataSource(@Qualifier("db1") DataSource db1,
                                         @Qualifier("db2") DataSource db2) {
        MultipleDataSource multipleDataSource = new MultipleDataSource();
        Map< Object, Object > targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceEnum.DB1.getValue(), db1);
        targetDataSources.put(DataSourceEnum.DB2.getValue(), db2);
        //添加数据源
        multipleDataSource.setTargetDataSources(targetDataSources);
        //设置默认数据源
        multipleDataSource.setDefaultTargetDataSource(db1);
        return multipleDataSource;
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(multipleDataSource(db1(),db2()));

        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactory.setConfiguration(configuration);
        //添加分页功能
        sqlSessionFactory.setPlugins(paginationInterceptor());
        return sqlSessionFactory.getObject();
    }
}

接下来需要具体的业务逻辑,在service层的类或者方法上面添加@DataSource注解来指定该业务需要用到的数据源,如下:

@Service
@DataSource(DataSourceEnum.DB2)
public class GatewayLogService {

    @Autowired
    private GatewayLogMapper mapper;

    @Override
    public Result<IPage<GatewayLog>> pageList(GatewayLogDTO gatewayLogDTO) {
        LambdaQueryWrapper<GatewayLog> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotEmpty(gatewayLogDTO.getPath()), GatewayLog::getPath, gatewayLogDTO.getPath());
        wrapper.like(StringUtils.isNotEmpty(gatewayLogDTO.getSourceServer()), GatewayLog::getSourceServer, gatewayLogDTO.getSourceServer());
        wrapper.like(StringUtils.isNotEmpty(gatewayLogDTO.getTargetServer()), GatewayLog::getTargetServer, gatewayLogDTO.getTargetServer());
        wrapper.eq(StringUtils.isNotEmpty(gatewayLogDTO.getMethod()), GatewayLog::getMethod, gatewayLogDTO.getMethod());
        wrapper.like(StringUtils.isNotEmpty(gatewayLogDTO.getRequestBody()), GatewayLog::getRequestBody, gatewayLogDTO.getRequestBody());
        wrapper.like(StringUtils.isNotEmpty(gatewayLogDTO.getResponse()), GatewayLog::getResponse, gatewayLogDTO.getResponse());
        wrapper.orderByDesc(GatewayLog::getId);

        IPage<GatewayLog> page = new Page<>(gatewayLogDTO.getPageNo(), gatewayLogDTO.getPageSize());

        return Result.success(mapper.selectPage(page, wrapper));
    }

}

启动服务,调用相关的接口,我们会在控制台看到如下信息:

说明数据源切换成功!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MybatisPlus配置双数据库驱动 的相关文章

随机推荐

  • 【从零到一的Raspberry】数莓派踩坑实录(二) 内核编译配置和模块安装

    写在前面 本次作业具有挑战性 不过不管哪一环节出错了 你都要知道如何把它还原到初始状态 这样你就不是在危险地操作 而有还原的保障 因此在第0节我会介绍一种还原数莓派系统的方法 这样你就可以在内核无法运行时还原到默认系统 后面从第一章开始 带
  • AD 利用IPC封装创建向导快速创建封装

    首先在扩展更新里查看是否有IPC封装 工具里面第二个会有很多常见封装类型 选择SOP NEXT 会填写一些数据 相对应在数据手册上进行填写即可 下图左上角问的是要不要加散热焊盘 散热焊盘主要看原件是否真实需要 上图要填的值一般来说默认就可以
  • Ubuntu无法连接网络?

    文章目录 适用情况 Windows网络配置和虚拟机网络配置 Windows网络适配器配置 Ubuntu设置静态IP 图形化界面操作 指令文件操作 如果重新设置好以后 依旧不行 适用情况 如果您无法知晓 虚拟机出现是什么问题 始终就是无法连接
  • 黑盒测试的范围内容

    1 功能错误或遗漏 2 界面错误 3 数据结构或外部数内容据库访问错误 4 性能错误 5 初始化和终止错误
  • 动态规划(js版)

    1 动态规划算法介绍 理解动态规划 知乎好文 LeetCode简单的动态规划题 斐波那契数 爬楼梯 使用最小花费爬楼梯 有点小坑 不同路径 不同路径 II 注意初始值的设置 最小路径和 LeetCode较难的动态规划题 343 整数拆分 9
  • 哈希(Hash)与算法的衡量

    对于map来说 背后就是平衡搜索二叉树 具体可见 https blog csdn net weixin 42513339 article details 88889306 空间复杂度为 O logN 对于unorder map来说 背后就是
  • ubuntu18.04安装xmind思维导图 + 创建软件的快捷方式

    ubuntu18 04安装xmind思维导图 sh文件运行小知识 创建快捷方式 1 下载linux版本的 zip压缩包 2 运行sudo setup sh 2 1 sh 文件相关知识 补充 3 启动xmind 3 1 启动失败 font f
  • ggplot2中的条形图 geom_bar()

    20150226 1 ggplot 能直接计算aes 中x变量各个分类的数目 所以可以直接用原始数据 而不用像plot 一样要table 数据 2 geom bar mapping NULL data NULL stat bin posit
  • 从零搭建 Spring Cloud 服务(超级详细)

    点击上方 Java后端 选择 设为星标 优质文章 及时送达 作者 Anakki 链接 blog csdn net qq 29519041 article details 85238270 这里会介绍很多基础知识 直接想开始搭建微服务的可以看
  • 小学思品课如何使用计算机教学设计,关于小学思品教学设计与反思

    关于小学思品教学设计与反思 小学思想品德节约用水教学设计与反思 节约用水 教学设计与反思 一 指导思想 品德与生活课 注重学生的实践与参与性 突出教学实效性 让学生通过丰富的教学活动去亲身体验 亲自感受水的重要与水资源的匮乏 从而形成自觉的
  • Win10 系统下VisualStudio2019 配置Open3D-0.15.2(C++)

    目录 一 下载Open3D 0 15 2 二 编译 font color dd00dd 1 新建文件 CmakeList txt TestVisualizer h TestVisualizer cpp font color dd00dd 2
  • 进程、线程与JVM、CLR

    进程和线程的关系 网上有一副很经典的图可以让我们来理解进程和线程的关系 下面这副图是一个双向多车道的道路图 假如我们把整条道路看成是一个 进程 的话 那么图中由白色虚线分隔开来的各个车道就是进程中的各个 线程 了 这副图出自 http ww
  • chroot命令的基本用法

    chroot 切换根目录 chroot PATH TO TEMPROOT COMMAND chroot test virrot bin bash 切换根目录 并明确指明运行那个目录下面的bash 例子 切换根目录 root gdy ftpf
  • 实战Elastic Stack分析K8S应用日志--部署logstash

    logstash从kafka取数据输出到es 部署logstash docker pull logstash 6 8 6 docker images grep logstash docker tag d0a2dac51fcb harbor
  • 【M malloc送书第二期】朋友圈大佬都去读研了,这份备考书单我码住了!

    文章目录 01 数据结构与算法分析 02 计算机网络 自顶向下方法 03 现代操作系统 04 深入理解计算机系统 01 概率论基础教程 原书第10版 03 线性代数及其应用 八九月的朋友圈刮起了一股晒通知书潮 频频有大佬晒出 研究生入学通知
  • JSONObject与JSONArray总结及部分使用

    例如 取出name4值过程步骤 1 将以上字符串转换为JSONArray对象 2 取出对象的第一项 JSONObject对象 3 取出name1的值JSONObject对象 4 取出name2的值JSONObject对象 5 取出name4
  • 【react】高阶函数_函数柯里化

    高阶函数 如果一个函数符合下面2个规范中的任何一个 那该函数就是高阶函数 1 若A函数 接受的参数是一个函数 那么A就可以称之为高阶函数 2 若A函数 调用的返回值依然是一个函数 那么A就可以称之为高阶函数 常见的高阶函数有 Promise
  • JetBrain系列软件使用

    一 PHPSTORM 非常好用的插件 支持对一些动态调用的函数快速跳到函数定义处 DynamicReturnTypePlugin FIle gt Settings gt Plugins gt Marketplace 输入 DynamicRe
  • 使用Python对一张图像进行高斯模糊

    import cv2 src cv2 imread test jpg numpy数组 第二个参数 高斯核的宽和高 建议是奇数 第三个参数 x和y轴的标准差 result cv GaussianBlur src 45 45 15 cv2 im
  • MybatisPlus配置双数据库驱动

    个人博客纯净版 MybatisPlus配置双数据库驱动 代码搬运工 最近项目中需要用到2种数据库驱动连接数据库 下面我们基于MybatisPlus实现一下 具体实现 1 在pom xml中添加如下依赖