فهرست منبع

TenantDsProcessor 接入动态数据源的加载

YunaiV 2 سال پیش
والد
کامیت
1b563fecaa
14فایلهای تغییر یافته به همراه246 افزوده شده و 31 حذف شده
  1. 10 1
      yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
  2. 59 4
      yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/dynamic/TenantDsProcessor.java
  3. 10 0
      yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkService.java
  4. 31 0
      yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkServiceImpl.java
  5. 20 0
      yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/db/DataSourceConfigServiceApi.java
  6. 35 0
      yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/db/dto/DataSourceConfigRespDTO.java
  7. 26 0
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/db/DataSourceConfigServiceApiImpl.java
  8. 3 0
      yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/convert/db/DataSourceConfigConvert.java
  9. 10 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApi.java
  10. 19 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java
  11. 4 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/tenant/TenantConvert.java
  12. 9 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java
  13. 2 6
      yudao-server/src/main/resources/application-dev.yaml
  14. 8 20
      yudao-server/src/main/resources/application-local.yaml

+ 10 - 1
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java

@@ -18,6 +18,9 @@ import cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter;
 import cn.iocoder.yudao.framework.web.config.WebProperties;
 import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
 import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
+import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
+import com.baomidou.dynamic.datasource.creator.DataSourceCreator;
+import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
 import com.baomidou.dynamic.datasource.processor.DsProcessor;
 import com.baomidou.dynamic.datasource.processor.DsSpelExpressionProcessor;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
@@ -36,6 +39,7 @@ import org.springframework.data.redis.cache.RedisCacheWriter;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.core.RedisTemplate;
 
+import javax.sql.DataSource;
 import java.util.Objects;
 
 @AutoConfiguration
@@ -68,7 +72,12 @@ public class YudaoTenantAutoConfiguration {
     }
 
     @Bean
-    public DsProcessor dsProcessor() {
+    public DsProcessor dsProcessor(
+//            TenantFrameworkService tenantFrameworkService,
+//                                   DataSource dataSource,
+//                                   DefaultDataSourceCreator dataSourceCreator
+    ) {
+//        TenantDsProcessor tenantDsProcessor = new TenantDsProcessor(tenantFrameworkService, dataSourceCreator);
         TenantDsProcessor tenantDsProcessor = new TenantDsProcessor();
         tenantDsProcessor.setNextProcessor(new DsSpelExpressionProcessor());
         return tenantDsProcessor;

+ 59 - 4
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/dynamic/TenantDsProcessor.java

@@ -1,18 +1,52 @@
 package cn.iocoder.yudao.framework.tenant.core.db.dynamic;
 
 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
+import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
+import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
+import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
 import com.baomidou.dynamic.datasource.processor.DsProcessor;
+import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
+import jodd.util.CollectionUtil;
+import lombok.RequiredArgsConstructor;
 import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.context.annotation.Lazy;
 
+import javax.annotation.Resource;
+import javax.sql.DataSource;
 import java.util.Objects;
 
 /**
  * 基于 {@link TenantDS} 的数据源处理器
  *
+ * 1. 如果有 @TenantDS 注解,返回该租户的数据源
+ * 2. 如果该租户的数据源未创建,则进行创建
+ *
  * @author 芋道源码
  */
+@RequiredArgsConstructor
 public class TenantDsProcessor extends DsProcessor {
 
+    /**
+     * 用于获取租户数据源配置的 Service
+     */
+    @Resource
+    @Lazy
+    private TenantFrameworkService tenantFrameworkService;
+
+    /**
+     * 动态数据源
+     */
+    @Resource
+    @Lazy  // 为什么添加 @Lazy 注解?因为它和 DynamicRoutingDataSource 相互依赖,导致无法初始化
+    private DynamicRoutingDataSource dynamicRoutingDataSource;
+
+    /**
+     * 用于创建租户数据源的 Creator
+     */
+    @Resource
+    @Lazy
+    private DefaultDataSourceCreator dataSourceCreator;
+
     @Override
     public boolean matches(String key) {
         return Objects.equals(key, TenantDS.KEY);
@@ -20,12 +54,33 @@ public class TenantDsProcessor extends DsProcessor {
 
     @Override
     public String doDetermineDatasource(MethodInvocation invocation, String key) {
+        // 获得数据源配置
         Long tenantId = TenantContextHolder.getRequiredTenantId();
-        // TODO 芋艿:临时测试
-        if (tenantId != 1) {
-            tenantId = 2L;
+        DataSourceProperty dataSourceProperty = tenantFrameworkService.getDataSourceProperty(tenantId);
+        // 创建 or 创建数据源,并返回数据源名字
+        return createDatasourceIfAbsent(dataSourceProperty);
+    }
+
+    private String createDatasourceIfAbsent(DataSourceProperty dataSourceProperty) {
+        // 1. 重点:如果数据源不存在,则进行创建
+        if (isDataSourceNotExist(dataSourceProperty)) {
+            // 问题一:为什么要加锁?因为,如果多个线程同时执行到这里,会导致多次创建数据源
+            // 问题二:为什么要使用 poolName 加锁?保证多个不同的 poolName 可以并发创建数据源
+            // 问题三:为什么要使用 intern 方法?因为,intern 方法,会返回一个字符串的常量池中的引用
+            // intern 的说明,可见 https://www.cnblogs.com/xrq730/p/6662232.html 文章
+            synchronized (dataSourceProperty.getPoolName().intern()) {
+                if (isDataSourceNotExist(dataSourceProperty)) {
+                    DataSource dataSource = dataSourceCreator.createDataSource(dataSourceProperty);
+                    dynamicRoutingDataSource.addDataSource(dataSourceProperty.getPoolName(), dataSource);
+                }
+            }
         }
-        return "tenant_" + tenantId + "_ds";
+        // 2. 返回数据源的名字
+        return dataSourceProperty.getPoolName();
+    }
+
+    private boolean isDataSourceNotExist(DataSourceProperty dataSourceProperty) {
+        return !dynamicRoutingDataSource.getDataSources().containsKey(dataSourceProperty.getPoolName());
     }
 
 }

+ 10 - 0
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkService.java

@@ -1,5 +1,7 @@
 package cn.iocoder.yudao.framework.tenant.core.service;
 
+import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
+
 import java.util.List;
 
 /**
@@ -23,4 +25,12 @@ public interface TenantFrameworkService {
      */
     void validTenant(Long id);
 
+    /**
+     * 获得租户对应的数据源配置
+     *
+     * @param id 租户编号
+     * @return 数据源配置
+     */
+    DataSourceProperty getDataSourceProperty(Long id);
+
 }

+ 31 - 0
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkServiceImpl.java

@@ -2,7 +2,10 @@ package cn.iocoder.yudao.framework.tenant.core.service;
 
 import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.framework.common.util.cache.CacheUtils;
+import cn.iocoder.yudao.module.infra.api.db.dto.DataSourceConfigRespDTO;
 import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
+import cn.iocoder.yudao.module.system.api.tenant.dto.TenantDataSourceConfigRespDTO;
+import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 import lombok.RequiredArgsConstructor;
@@ -56,6 +59,28 @@ public class TenantFrameworkServiceImpl implements TenantFrameworkService {
 
             });
 
+    /**
+     * 针对 {@link #getDataSourceProperty(Long)} 的缓存
+     */
+    private final LoadingCache<Long, DataSourceProperty> dataSourcePropertyCache = CacheUtils.buildAsyncReloadingCache(
+            Duration.ofMinutes(1L), // 过期时间 1 分钟
+            new CacheLoader<Long, DataSourceProperty>() {
+
+                @Override
+                public DataSourceProperty load(Long id) {
+                    // 获得租户对应的数据源配置
+                    TenantDataSourceConfigRespDTO dataSourceConfig = tenantApi.getTenantDataSourceConfig(id);
+                    if (dataSourceConfig == null) {
+                        return null;
+                    }
+                    // 转换成 dynamic-datasource 配置
+                    return new DataSourceProperty()
+                            .setPoolName(dataSourceConfig.getName()).setUrl(dataSourceConfig.getUrl())
+                            .setUsername(dataSourceConfig.getUsername()).setPassword(dataSourceConfig.getPassword());
+                }
+
+            });
+
     @Override
     @SneakyThrows
     public List<Long> getTenantIds() {
@@ -70,4 +95,10 @@ public class TenantFrameworkServiceImpl implements TenantFrameworkService {
         }
     }
 
+    @Override
+    @SneakyThrows
+    public DataSourceProperty getDataSourceProperty(Long id) {
+        return dataSourcePropertyCache.get(id);
+    }
+
 }

+ 20 - 0
yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/db/DataSourceConfigServiceApi.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.infra.api.db;
+
+import cn.iocoder.yudao.module.infra.api.db.dto.DataSourceConfigRespDTO;
+
+/**
+ * 数据源配置 API 接口
+ *
+ * @author 芋道源码
+ */
+public interface DataSourceConfigServiceApi {
+
+    /**
+     * 获得数据源配置
+     *
+     * @param id 编号
+     * @return 数据源配置
+     */
+    DataSourceConfigRespDTO getDataSourceConfig(Long id);
+
+}

+ 35 - 0
yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/db/dto/DataSourceConfigRespDTO.java

@@ -0,0 +1,35 @@
+package cn.iocoder.yudao.module.infra.api.db.dto;
+
+import lombok.Data;
+
+/**
+ * 数据源配置 Response DTO
+ *
+ * @author 芋道源码
+ */
+@Data
+public class DataSourceConfigRespDTO {
+
+    /**
+     * 主键编号
+     */
+    private Long id;
+    /**
+     * 连接名
+     */
+    private String name;
+
+    /**
+     * 数据源连接
+     */
+    private String url;
+    /**
+     * 用户名
+     */
+    private String username;
+    /**
+     * 密码
+     */
+    private String password;
+
+}

+ 26 - 0
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/db/DataSourceConfigServiceApiImpl.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.module.infra.api.db;
+
+import cn.iocoder.yudao.module.infra.api.db.dto.DataSourceConfigRespDTO;
+import cn.iocoder.yudao.module.infra.convert.db.DataSourceConfigConvert;
+import cn.iocoder.yudao.module.infra.service.db.DataSourceConfigService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * 数据源配置 API 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+public class DataSourceConfigServiceApiImpl implements DataSourceConfigServiceApi {
+
+    @Resource
+    private DataSourceConfigService dataSourceConfigService;
+
+    @Override
+    public DataSourceConfigRespDTO getDataSourceConfig(Long id) {
+        return DataSourceConfigConvert.INSTANCE.convert02(dataSourceConfigService.getDataSourceConfig(id));
+    }
+
+}

+ 3 - 0
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/convert/db/DataSourceConfigConvert.java

@@ -4,6 +4,7 @@ import java.util.*;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 
+import cn.iocoder.yudao.module.infra.api.db.dto.DataSourceConfigRespDTO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 import cn.iocoder.yudao.module.infra.controller.admin.db.vo.*;
@@ -27,4 +28,6 @@ public interface DataSourceConfigConvert {
 
     List<DataSourceConfigRespVO> convertList(List<DataSourceConfigDO> list);
 
+    DataSourceConfigRespDTO convert02(DataSourceConfigDO bean);
+
 }

+ 10 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApi.java

@@ -1,5 +1,7 @@
 package cn.iocoder.yudao.module.system.api.tenant;
 
+import cn.iocoder.yudao.module.system.api.tenant.dto.TenantDataSourceConfigRespDTO;
+
 import java.util.List;
 
 /**
@@ -23,4 +25,12 @@ public interface TenantApi {
      */
     void validateTenant(Long id);
 
+    /**
+     * 获得租户的数据源配置
+     *
+     * @param tenantId 租户编号
+     * @return 数据源配置
+     */
+    TenantDataSourceConfigRespDTO getTenantDataSourceConfig(Long tenantId);
+
 }

+ 19 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java

@@ -1,5 +1,9 @@
 package cn.iocoder.yudao.module.system.api.tenant;
 
+import cn.iocoder.yudao.module.infra.api.db.DataSourceConfigServiceApi;
+import cn.iocoder.yudao.module.system.api.tenant.dto.TenantDataSourceConfigRespDTO;
+import cn.iocoder.yudao.module.system.convert.tenant.TenantConvert;
+import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
 import cn.iocoder.yudao.module.system.service.tenant.TenantService;
 import org.springframework.stereotype.Service;
 
@@ -17,6 +21,9 @@ public class TenantApiImpl implements TenantApi {
     @Resource
     private TenantService tenantService;
 
+    @Resource
+    private DataSourceConfigServiceApi dataSourceConfigServiceApi;
+
     @Override
     public List<Long> getTenantIdList() {
         return tenantService.getTenantIdList();
@@ -27,4 +34,16 @@ public class TenantApiImpl implements TenantApi {
         tenantService.validTenant(id);
     }
 
+    @Override
+    public TenantDataSourceConfigRespDTO getTenantDataSourceConfig(Long tenantId) {
+        // 获得租户信息
+        TenantDO tenant = tenantService.getTenant(tenantId);
+        if (tenant == null) {
+            return null;
+        }
+        // 获得租户的数据源配置
+        return TenantConvert.INSTANCE.convert(
+                dataSourceConfigServiceApi.getDataSourceConfig(tenant.getDatasourceConfigId()));
+    }
+
 }

+ 4 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/tenant/TenantConvert.java

@@ -1,6 +1,8 @@
 package cn.iocoder.yudao.module.system.convert.tenant;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.infra.api.db.dto.DataSourceConfigRespDTO;
+import cn.iocoder.yudao.module.system.api.tenant.dto.TenantDataSourceConfigRespDTO;
 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantCreateReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExcelVO;
 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantRespVO;
@@ -42,4 +44,6 @@ public interface TenantConvert {
         return reqVO;
     }
 
+    TenantDataSourceConfigRespDTO convert(DataSourceConfigRespDTO bean);
+
 }

+ 9 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java

@@ -79,4 +79,13 @@ public class TenantDO extends BaseDO {
      */
     private Integer accountCount;
 
+    /**
+     * 数据源配置编号
+     *
+     * 多租户采用“分库”方案时,通过该字段配置所在数据源
+     *
+     * 关联 DataSourceConfigDO 的 id 字段
+     */
+    private Long datasourceConfigId;
+
 }

+ 2 - 6
yudao-server/src/main/resources/application-dev.yaml

@@ -44,15 +44,11 @@ spring:
       primary: master
       datasource:
         master:
-          name: ruoyi-vue-pro
-          url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
-          driver-class-name: com.mysql.jdbc.Driver
+          url: jdbc:mysql://400-infra.server.iocoder.cn:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
           username: root
           password: 3WLiVUBEwTbvAfsh
         slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
-          name: ruoyi-vue-pro
-          url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
-          driver-class-name: com.mysql.jdbc.Driver
+          url: jdbc:mysql://400-infra.server.iocoder.cn:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
           username: root
           password: 3WLiVUBEwTbvAfsh
 

+ 8 - 20
yudao-server/src/main/resources/application-local.yaml

@@ -44,37 +44,25 @@ spring:
       primary: master
       datasource:
         master:
-          name: ruoyi-vue-pro-master
-          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true # MySQL Connector/J 8.X 连接的示例
-          #          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
-          #          url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
+          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro-master?useSSL=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true # MySQL Connector/J 8.X 连接的示例
+          #          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro-master?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
+          #          url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
           #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
-          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例
+          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro-master # SQLServer 连接的示例
           username: root
           password: 123456
         #          username: sa
         #          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
         slave: # 模拟从库,可根据自己需要修改
-          name: ruoyi-vue-pro
-          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true # MySQL Connector/J 8.X 连接的示例
-          #          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
-          #          url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
+          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true # MySQL Connector/J 8.X 连接的示例
+          #          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
+          #          url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
           #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
-          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例
+          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro # SQLServer 连接的示例
           username: root
           password: 123456
   #          username: sa
   #          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
-        tenant_1_ds:
-          name: tenant_1
-          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro-tenant-a?useSSL=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
-          username: root
-          password: 123456
-        tenant_2_ds:
-          name: tenant_2
-          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro-tenant-b?useSSL=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
-          username: root
-          password: 123456
 
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
   redis: