关于MybatisPlus配置双数据库驱动连接数据库问题


Posted in Java/Android onJanuary 22, 2022

最近项目中需要用到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();
    }
}

6、新建DataSource注解,如下:

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
 
    DataSourceEnum value() default DataSourceEnum.DB1;
}

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

@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();
    }
}

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

@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));
    }
 
}

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

关于MybatisPlus配置双数据库驱动连接数据库问题

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

到此这篇关于关于MybatisPlus配置双数据库驱动连接数据库问题的文章就介绍到这了,更多相关MybatisPlus配置双数据库内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Java/Android 相关文章推荐
Java内存模型之happens-before概念详解
Jun 13 Java/Android
分析Netty直接内存原理及应用
Jun 14 Java/Android
SpringBoot2 参数管理实践之入参出参与校验的方式
Jun 16 Java/Android
Spring中bean的生命周期之getSingleton方法
Jun 30 Java/Android
logback如何自定义日志存储
Aug 30 Java/Android
详解Java七大阻塞队列之SynchronousQueue
Sep 04 Java/Android
Spring-cloud Config Server的3种配置方式
Sep 25 Java/Android
Java8中接口的新特性使用指南
Nov 01 Java/Android
深入浅出讲解Java8函数式编程
Jan 18 Java/Android
Android 界面一键变灰 深色主题工具类
Apr 28 Java/Android
java版 联机五子棋游戏
May 04 Java/Android
openGauss数据库JDBC环境连接配置的详细过程(Eclipse)
Jun 01 Java/Android
JavaCV实现照片马赛克效果
Jan 22 #Java/Android
maven依赖的version声明控制方式
深入浅出讲解Java8函数式编程
Jan 18 #Java/Android
关于maven依赖 ${xxx.version}报错问题
Jan 18 #Java/Android
Eclipse+Java+Swing+Mysql实现电影购票系统(详细代码)
关于Spring配置文件加载方式变化引发的异常详解
Jan 18 #Java/Android
springboot中的pom文件 project报错问题
Jan 18 #Java/Android
You might like
php中sprintf与printf函数用法区别解析
2014/02/17 PHP
PHP获取文件相对路径的方法
2015/02/26 PHP
thinkphp隐藏index.php/home并允许访问其他模块的实现方法
2016/10/13 PHP
Laravel框架实现即点即改功能的方法分析
2019/10/31 PHP
PHP使用gearman进行异步的邮件或短信发送操作详解
2020/02/27 PHP
用javascript父窗口控制只弹出一个子窗口
2007/04/10 Javascript
js的闭包的一个示例说明
2008/11/18 Javascript
在vs2010中调试javascript代码方法
2011/02/11 Javascript
js中 关于undefined和null的区别介绍
2013/04/16 Javascript
jquery.cookie用法详细解析
2013/12/18 Javascript
使用Vue.js创建一个时间跟踪的单页应用
2016/11/28 Javascript
jQuery插件扩展操作入门示例
2017/01/16 Javascript
Javascript同时声明一连串(多个)变量的方法
2017/01/23 Javascript
正则表达式基本语法及表单验证操作详解【基于JS】
2017/04/07 Javascript
关于vue.extend和vue.component的区别浅析
2017/08/16 Javascript
基于vue.js 2.x的虚拟滚动条的示例代码
2018/01/23 Javascript
vue.js引入外部CSS样式和外部JS文件的方法
2019/01/06 Javascript
vue中过滤器filter的讲解
2019/01/21 Javascript
layer弹出层显示在top顶层的方法
2019/09/11 Javascript
Egg Vue SSR 服务端渲染数据请求与asyncData
2019/11/24 Javascript
基于vue.js实现购物车
2020/01/15 Javascript
jQuery中event.target和this的区别详解
2020/08/13 jQuery
vue使用svg文件补充-svg放大缩小操作(使用d3.js)
2020/09/22 Javascript
[32:56]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第二场 12.11
2020/12/16 DOTA
Python实现的插入排序,冒泡排序,快速排序,选择排序算法示例
2019/05/04 Python
解决yum对python依赖版本问题
2019/07/05 Python
django迁移数据库错误问题解决
2019/07/29 Python
django正续或者倒序查库实例
2020/05/19 Python
Python求区间正整数内所有素数之和的方法实例
2020/10/13 Python
css3进阶之less实现星空动画的示例代码
2019/09/10 HTML / CSS
高级护理实习生自荐信
2013/09/28 职场文书
高中毕业生自我鉴定
2013/11/03 职场文书
模特大赛策划方案
2014/05/28 职场文书
新学期红领巾广播稿
2014/10/04 职场文书
Oracle安装TNS_ADMIN环境变量设置参考
2021/11/01 Oracle
如何基于python实现单目三维重建详解
2022/06/25 Python