spring项目如何配置多数据源(已上生产,亲测有效)

 更新时间:2023年12月29日 09:21:15   作者:陈賝  
这篇文章主要介绍了spring项目如何配置多数据源(已上生产,亲测有效),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

方式一(推荐)

注解形式添加

引入依赖

      <!-- dynamic-datasource 多数据源-->
      <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
        <version>3.5.2</version>
      </dependency>

修改配置文件

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    dynamic:
      # 设置默认的数据源或者数据源组,默认值即为 master
      primary: master
      # 严格模式 匹配不到数据源则报错
      strict: true
      datasource:
        # 主库数据源
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          username: root
          password: xxxxx
          url: jdbc:mysql://127.0.0.1:3306/ifssc-iot?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai
        # 从库库数据源
        slave:
          driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
          url: jdbc:TAOS-RS://127.0.0.1:6041/power?charset=UTF-8&locale=en_US.UTF-8&timezone=UTC-8
          username: root
          password: xxxxx
        # 从库库数据源
        slave2:
          driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
          url: jdbc:TAOS-RS://127.0.0.1:6041/power?charset=UTF-8&locale=en_US.UTF-8&timezone=UTC-8
          username: root
          password: xxxxx
      druid:
        enable: true
        max-active: 50
        min-idle: 50
        initial-size: 50
        max-wait: 60000
        time-between-eviction-runs-millis: 60000
        validation-query: select server_status()
        test-on-return: false
        test-while-idle: true
        test-on-borrow: false
        async-close-connection-enable: true
        async-init: true

使用 直接加在使用的方法上即可

  • @Slave
  • @DS(“slave2”)
  • @DS(“xxx”)
    @Slave
    public ResultVO test() {
        LambdaQueryWrapper<Temperature> lqw = new QueryWrapper<Temperature>().lambda()
                .eq(Temperature::getLocation, "杭州")
                .last("limit 10");
        List<Temperature> temperatureList = temperatureMapper.selectList(lqw);
        return ResultVO.success(temperatureList);
    }
    
    @Slave2
    public ResultVO test() {
        LambdaQueryWrapper<Temperature> lqw = new QueryWrapper<Temperature>().lambda()
                .eq(Temperature::getLocation, "杭州")
                .last("limit 10");
        List<Temperature> temperatureList = temperatureMapper.selectList(lqw);
        return ResultVO.success(temperatureList);
    }

方式二:分开配置mapper,不影响之前的mapper

修改配置文件,添加数据源配置

修改application.yaml

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      db1:
        enable: true
        driver-class-name: com.mysql.cj.jdbc.Driver
        max-active: 100
        min-idle: 100
        initial-size: 100
        max-wait: 60000
        time-between-eviction-runs-millis: 60000
        validation-query: SELECT 1 FROM DUAL
        jdbc-url: jdbc:mysql://***:3306/***2?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai
        username: root
        password: ***
        test-on-return: false
        test-while-idle: true
        test-on-borrow: false
        async-close-connection-enable: true
        async-init: true
        use-unfair-lock: true
      db2:
        enable: true
        driver-class-name: com.mysql.cj.jdbc.Driver
        max-active: 100
        min-idle: 100
        initial-size: 100
        max-wait: 60000
        time-between-eviction-runs-millis: 60000
        validation-query: SELECT 1 FROM DUAL
        jdbc-url: jdbc:mysql://***:3306/***1?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai
        username: root
        password: ***
        test-on-return: false
        test-while-idle: true
        test-on-borrow: false
        async-close-connection-enable: true
        async-init: true
        use-unfair-lock: true
#mybatis
mybatis-plus:
  type-aliases-package: com.***.cloud.common.entity   # 所有Entity别名类所在包
  mapper-locations: classpath:mapper/**/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 配置打印日志
    call-setters-on-nulls: true
    cache-enabled: false   

添加配置类

主数据源配置

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * 主数据源配置
 *
 * @author 陈琛
 * @date 2022/05/09
 */
@Configuration
@MapperScan(basePackages = {"com.xxx.cloud.platform.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory")
public class PrimaryDataSourceConfig {

    @Resource
    private MybatisPlusInterceptor mybatisPlusInterceptor;

    @Value("${mybatis-plus.mapper-locations}")
    private String locationPattern;

    @Value("${mybatis-plus.type-aliases-package}")
    private String typeAliasesPackage;

    @Bean
    @Scope(value = "prototype")
    @ConfigurationProperties(prefix = "mybatis-plus.configuration")
    public MybatisConfiguration getCfg() {
        return new MybatisConfiguration();
    }


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

    @Bean(name = "sqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setPlugins(mybatisPlusInterceptor);
        bean.setConfiguration(getCfg());
        bean.setTypeAliasesPackage(typeAliasesPackage);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(locationPattern));
        return bean.getObject();
    }

    @Bean(name = "transactionManager")
    @Primary
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "sqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

次数据源配置

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * 第二个数据源配置
 *
 * @author 陈琛
 * @date 2022/05/09
 */
@Configuration
@MapperScan(basePackages = {"com.xxx.cloud.platform.websiteMapper"}, sqlSessionFactoryRef = "sqlSessionFactory2")
public class SecondDataSourceConfig {

    @Resource
    private MybatisPlusInterceptor mybatisPlusInterceptor;

    @Value("${mybatis-plus.mapper-locations}")
    private String locationPattern;

    @Value("${mybatis-plus.type-aliases-package}")
    private String typeAliasesPackage;

    @Resource
    private MybatisConfiguration mybatisConfiguration;

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

    @Bean(name = "sqlSessionFactory2")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource2") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setPlugins(mybatisPlusInterceptor);
        bean.setConfiguration(mybatisConfiguration);
        bean.setTypeAliasesPackage(typeAliasesPackage);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(locationPattern));
        return bean.getObject();
    }

    @Bean(name = "transactionManager2")
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSource2") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "sqlSessionTemplate2")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

数据源分配

  • 主数据源正常使用之前的mapper
  • 次数据源使用之后新建的websiteMapper

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • JVM之内存分配和回收机制

    JVM之内存分配和回收机制

    本篇主要介绍JVM内存分配和回收策略,内容主要节选自《深入理解java虚拟机》,需要的朋友可以参考下
    2023-05-05
  • SpringBoot使用AOP记录接口操作日志详解

    SpringBoot使用AOP记录接口操作日志详解

    这篇文章主要为大家详细介绍了SpringBoot使用AOP记录接口操作日志,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • Caused by: java.io.IOException: DerInputStream.getLength(): lengthTag=111

    Caused by: java.io.IOException: DerInputStrea

    这篇文章主要介绍了Caused by: java.io.IOException: DerInputStream.getLength(): lengthTag=111, too big,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-10-10
  • 浅谈Java线程池的7大核心参数

    浅谈Java线程池的7大核心参数

    本篇文章基于正在看这篇文章的你已经具备了基本的Java并发的相关知识.如果对于Java并发编程一无所知的话,请先看看Java并发编程的一些前导基础知识,文中有非常详细的图文示例及代码,,需要的朋友可以参考下
    2021-05-05
  • Map之computeIfAbsent使用解读

    Map之computeIfAbsent使用解读

    `computeIfAbsent`是Java 8引入的一个Map接口方法,用于简化在Map中获取值的操作,如果指定的键不存在,它会调用提供的函数生成一个新的值,并将其与键关联,这种方法减少了手动检查和插入的样板代码,使代码更加简洁和易读
    2025-02-02
  • Springboot访问html页面的教程详解

    Springboot访问html页面的教程详解

    这篇文章主要介绍了Springboot访问html页面的教程,本文图文并茂给大家介绍的非常详细,需要的朋友可以参考下
    2018-03-03
  • Spring Boot Filter 过滤器的使用方式

    Spring Boot Filter 过滤器的使用方式

    这篇文章主要介绍了Spring Boot Filter 过滤器的使用方式,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • Java FileDescriptor总结_动力节点Java学院整理

    Java FileDescriptor总结_动力节点Java学院整理

    FileDescriptor 是“文件描述符”。可以被用来表示开放文件、开放套接字等。接下来通过本文给大家分享Java FileDescriptor总结,感兴趣的朋友一起学习吧
    2017-05-05
  • Java回调函数与观察者模式实例代码

    Java回调函数与观察者模式实例代码

    这篇文章主要介绍了Java回调函数与观察者模式实例代码,简单介绍了使用观察者模式的场景,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • Java JSON提取工具JsonExtractor的使用

    Java JSON提取工具JsonExtractor的使用

    本文主要介绍了Java JSON提取工具JsonExtractor的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05

最新评论