记一次SpringBoot+myBatisPlus多数据源配置

本次项目涉及三组数据源,介绍了两种数据源配置方式,即YAML和DynamicDataSourceProvider,还说明了数据源的使用方法。指出上述配置对分库分表不灵活,给出手动配置分库分表数据源的方法,配置后新增分表时可自动根据逻辑表创建分表。

本次项目中涉及了三组数据源:系统数据的mysql、tdEngine、shardingsphere分库分表的mysql。具体数据源的yml配置如下:

一、数据源配置1——YAML

spring:
   datasource:
    dynamic:
      primary: base
      strict: true
      datasource:
        base:
          username: ${
   
   MYSQL_USER}
          password: ${
   
   MYSQL_PWD}
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://${
   
   MYSQL_HOST}:${
   
   MYSQL_PORT}/base?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8&enabledTLSProtocols=TLSv1.2&useSSL=false
          name: HikariCP-1
          hikari:
            pool-name: HikaraPool-1
            connection-timeout: 30000
            idle-timeout: 600000
            max-lifetime: 1800000
            maximum-pool-size: 6
            minimum-idle: 5
        detect:
          username: root
          password: taosdata
          driver-class-name: com.taosdata.jdbc.TSDBDriver
          url: jdbc:TAOS://${
   
   TAOS_HOST}:${
   
   TAOS_PORT}/detect
          name: HikariCP-2
          hikari:
            pool-name: HikaraPool-2
            connection-timeout: 30000
            idle-timeout: 600000
            max-lifetime: 1800000
            maximum-pool-size: 15
            minimum-idle: 5
  shardingsphere:
    # 打印sql
    props:
      sql-show: true
    datasource:
      dta_data:
        type: com.zaxxer.hikari.HikariDataSource
        url: jdbc:mysql://${
   
   MYSQL_HOST}:${
   
   MYSQL_PORT}/dta_data?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8&enabledTLSProtocols=TLSv1.2&useSSL=false
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: ${
   
   MYSQL_USER}
        password: ${
   
   MYSQL_PWD}
    rules:
      table1: dta_data
      table2: dta_data

二、数据源配置2——DynamicDataSourceProvider

使用DynamicDataSourceProvider后,可以用mybatis的@DS注解很方便地使用数据源了。

配置类如下:

private static final String SHARDING_DATA_SOURCE_NAME = "sharding";
/**
 * 动态数据源配置项
 */
@Autowired
private DynamicDataSourceProperties dynamicDataSourceProperties;

@Lazy
@Resource
private ShardingSphereDataSource shardingSphereDataSource;

  @Bean
    public DynamicDataSourceProvider dynamicDataSourceProvider() {
   
   
        Map<String, DataSourceProperty> datasourceMap = dynamicDataSourceProperties.getDatasource();
        return new AbstractDataSourceProvider() {
   
   
            @Override
            public Map<String, DataSource> loadDataSources() {
   
   
                Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);

                // 将 shardingjdbc 管理的数据源也交给动态数据源管理
                dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingSphereDataSource);
                return dataSourceMap;
            }
        };
    }

    /**
     * 将动态数据源设置为首选的
     * 当spring存在多个数据源时, 自动注入的是首选的对象
     * 设置为主要的数据源之后,就可以支持shardingjdbc原生的配置方式了
     */
    @Primary
    @Bean
    public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
   
   
        DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
        dataSource.setPrimary(dynamicDataSourceProperties.getPrimary());
        dataSource.setStrict(dynamicDataSourceProperties.getStrict());
        dataSource.setStrategy(dynamicDataSourceProperties.getStrategy());
        dataSource.setProvider(dynamicDataSourceProvider);
        dataSource.setP6spy(dynamicDataSourceProperties.getP6spy());
//        dataSource.setSeata(dynamicDataSourceProperties.getSeata());  // 如果报错,可能是Spring版本问题,注释即可。
        return dataSource;
    }

三、数据源使用

  • 注解方式使用:

在mapper接口上或者具体的使用mapper的接口或者继承myBatis IService的接口上用@DS(“数据源名称”),即可使用对应的数据源。

示例如下:

// 用法1:在接口上面
@DS("sharding")
public interface MyServerI extends IService<MyPo> {
   
   
    boolean refreshMyPo(MyPo mypo);
}

// 在具体方法上
 @DS("sharding")
 @Override
 public boolean saveMyPo(MyPo myPo) {
   
   
     return myServerI.save(myPo);
 }
  • 从DynamicDataSourceProvider中获取数据源

    示例如下

@Autowired
private DynamicRoutingDataSource routingDataSource;

public boolean insertDetectResult(DetectionItemResult detectionItemResult) {
   
   
        // 1、查询
        String qry = "xxxxx";
        try (
                Connection connection = routingDataSource.getDataSource("detect").getConnection();
                Statement stmt = connection.createStatement()
        ) {
   
   
            ResultSet resultSet = stmt.executeQuery(qry);
         // .....
        } catch (Exception e) {
   
   
            log.error("异常:", e);
        }
        return true;
    }

但是上面的配置对分库分表不灵活,当产生新的分表时,无法自动创建实际使用的数据表。可以通过手动配置分库分表的数据源。示例如下:

彩蛋:手动配置分库分表数据源

  1. 继承MybatisPlusAutoConfiguration,获取yml中配置的数据源信息。
  2. ShardingSphereDataSourceFactory.createDataSource()创建分库分表数据源。
    具体代码示例如下:

//-----shardingsphere数据源配置yml解析

@Data
@Component
@ConfigurationProperties(prefix = "spring.shardingsphere")
public class MultipleDbConfiguration {
   
   

    private Map<String, Datasource> datasource;
    private Map<String, String> rules;

    @Data
    public static class Datasource {
   
   
        private String url;
        private String driverClassName;
        private String username;
        private String password;
    }
}
Spring Boot应用中使用MyBatisPlus并集成多数据源的情况下,如果需要对数据库密码进行加密存储,通常会使用环境变量或者外部安全配置工具(如Vault、KMS等)。但在YAML配置文件中直接操作加密可能会复杂一些。 首先,在YAML中,你可以分别为每个数据源定义一个独立的`spring.datasource`块,并将密码字段明文列出。例如: ```yaml dataSourceA: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db1 username: db1_user password: <plain-text-password> dataSourceB: driver-class-name: com.alibaba.druid.pool.DruidDriver url: jdbc:mysql://localhost:3307/db2 username: db2_user password: <plain-text-password> ``` 然后,为了密码加密,你可以选择在运行时动态加载密钥来解密密码。一种常见的做法是在启动类(如@SpringBootApplication)中读取环境变量或者从外部配置服务获取加密后的密码,再将其解密。这通常涉及到Spring Security的环境变量读取,或者其他加密库的支持。 ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Value("${db1_password}") private String db1EncryptedPassword; // ...其他配置... @Bean public DataSource dataSourceA() { DataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/db1"); dataSource.setUsername("db1_user"); // 使用解密函数处理密码 dataSource.setPassword(decrypt(db1EncryptedPassword)); return dataSource; } // ...类似地为dataSourceB配置... private String decrypt(String encrypted) { // 这里可以使用加解密库(如BCrypt或Jasypt)提供的方法解密 // 示例:return BCryptUtil.decrypt(encrypted); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值