Commit 61799385c9d55dabe0c5d1caf52f5bbb9cba3efd

Authored by 芋道源码
Committed by Gitee
2 parents 4a322ed7 d77481dd

!28 完成多数据源配置

Merge pull request !28 from timfruit/feature/multi-datasource
Showing 22 changed files with 235 additions and 569 deletions
README.md
@@ -35,12 +35,12 @@ @@ -35,12 +35,12 @@
35 | | 部门管理 | 配置系统组织机构(公司、部门、小组),树结构展现支持数据权限 | 35 | | 部门管理 | 配置系统组织机构(公司、部门、小组),树结构展现支持数据权限 |
36 | | 岗位管理 | 配置系统用户所属担任职务 | 36 | | 岗位管理 | 配置系统用户所属担任职务 |
37 | | 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 | 37 | | 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 |
38 -| | 通知公告 | 系统通知公告信息发布维护 | 38 +| 🚀 | 短信管理 | 短信渠道、短息模板、短信日志,对接阿里云、云片等主流短信平台 |
39 | 🚀 | 操作日志 | 系统正常操作日志记录和查询,集成 Swagger 生成日志内容 | 39 | 🚀 | 操作日志 | 系统正常操作日志记录和查询,集成 Swagger 生成日志内容 |
40 | | 登录日志 | 系统登录日志记录查询包含登录异常 | 40 | | 登录日志 | 系统登录日志记录查询包含登录异常 |
  41 +| | 通知公告 | 系统通知公告信息发布维护 |
41 42
42 计划新增功能: 43 计划新增功能:
43 -* 短信  
44 * 邮件 44 * 邮件
45 * 钉钉、飞书等通知 45 * 钉钉、飞书等通知
46 46
@@ -87,14 +87,15 @@ @@ -87,14 +87,15 @@
87 87
88 ## 技术栈 88 ## 技术栈
89 89
90 -**后端** 90 +### 后端
91 91
92 | 框架 | 说明 | 版本 | 学习指南 | 92 | 框架 | 说明 | 版本 | 学习指南 |
93 | --- | --- | --- | --- | 93 | --- | --- | --- | --- |
94 | [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.4.2 | [文档](https://github.com/YunaiV/SpringBoot-Labs) | 94 | [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.4.2 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
95 | [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 | | 95 | [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 | |
96 | [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.4 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | 96 | [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.4 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
97 -| [MyBatis-Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.4.1 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) | 97 +| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.4.1 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
  98 +| [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 3.3.2 | [文档](hhttp://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
98 | [Redis](https://redis.io/) | key-value 数据库 | 5.0 | | 99 | [Redis](https://redis.io/) | key-value 数据库 | 5.0 | |
99 | [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.1.46 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) | 100 | [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.1.46 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) |
100 | [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.4.2 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) | 101 | [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.4.2 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
@@ -111,7 +112,7 @@ @@ -111,7 +112,7 @@
111 | [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.7.0 | - | 112 | [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.7.0 | - |
112 | [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 3.6.28 | - | 113 | [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 3.6.28 | - |
113 114
114 -**前端** 115 +### 前端
115 116
116 | 框架 | 说明 | 版本 | 117 | 框架 | 说明 | 版本 |
117 | --- | --- | --- | 118 | --- | --- | --- |
@@ -30,6 +30,7 @@ @@ -30,6 +30,7 @@
30 <mysql-connector-java.version>5.1.46</mysql-connector-java.version> 30 <mysql-connector-java.version>5.1.46</mysql-connector-java.version>
31 <druid.version>1.2.4</druid.version> 31 <druid.version>1.2.4</druid.version>
32 <mybatis-plus.version>3.4.2</mybatis-plus.version> 32 <mybatis-plus.version>3.4.2</mybatis-plus.version>
  33 + <dynamic-datasource.version>3.3.2</dynamic-datasource.version>
33 <redisson.version>3.15.1</redisson.version> 34 <redisson.version>3.15.1</redisson.version>
34 <!-- Config 配置中心相关 --> 35 <!-- Config 配置中心相关 -->
35 <apollo.version>1.7.0</apollo.version> 36 <apollo.version>1.7.0</apollo.version>
@@ -139,6 +140,11 @@ @@ -139,6 +140,11 @@
139 <artifactId>mybatis-plus-boot-starter</artifactId> 140 <artifactId>mybatis-plus-boot-starter</artifactId>
140 <version>${mybatis-plus.version}</version> 141 <version>${mybatis-plus.version}</version>
141 </dependency> 142 </dependency>
  143 + <dependency>
  144 + <groupId>com.baomidou</groupId>
  145 + <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <!-- 多数据源 -->
  146 + <version>${dynamic-datasource.version}</version>
  147 + </dependency>
142 148
143 <dependency> 149 <dependency>
144 <groupId>org.redisson</groupId> 150 <groupId>org.redisson</groupId>
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataScope.java deleted
1 -package com.ruoyi.common.annotation;  
2 -  
3 -import java.lang.annotation.Documented;  
4 -import java.lang.annotation.ElementType;  
5 -import java.lang.annotation.Retention;  
6 -import java.lang.annotation.RetentionPolicy;  
7 -import java.lang.annotation.Target;  
8 -  
9 -/**  
10 - * 数据权限过滤注解  
11 - *  
12 - * @author ruoyi  
13 - */  
14 -@Target(ElementType.METHOD)  
15 -@Retention(RetentionPolicy.RUNTIME)  
16 -@Documented  
17 -public @interface DataScope {  
18 - /**  
19 - * 部门表的别名  
20 - */  
21 - public String deptAlias() default "";  
22 -  
23 - /**  
24 - * 用户表的别名  
25 - */  
26 - public String userAlias() default "";  
27 -}  
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataScopeAspect.java deleted
1 -package com.ruoyi.framework.aspectj;  
2 -  
3 -import java.lang.reflect.Method;  
4 -  
5 -import org.aspectj.lang.JoinPoint;  
6 -import org.aspectj.lang.Signature;  
7 -import org.aspectj.lang.annotation.Aspect;  
8 -import org.aspectj.lang.annotation.Before;  
9 -import org.aspectj.lang.annotation.Pointcut;  
10 -import org.aspectj.lang.reflect.MethodSignature;  
11 -import org.springframework.stereotype.Component;  
12 -import com.ruoyi.common.annotation.DataScope;  
13 -import com.ruoyi.common.core.domain.BaseEntity;  
14 -import com.ruoyi.common.core.domain.entity.SysRole;  
15 -import com.ruoyi.common.core.domain.entity.SysUser;  
16 -import com.ruoyi.common.core.domain.model.LoginUser;  
17 -import com.ruoyi.common.utils.ServletUtils;  
18 -import com.ruoyi.common.utils.StringUtils;  
19 -import com.ruoyi.common.utils.spring.SpringUtils;  
20 -import com.ruoyi.framework.web.service.TokenService;  
21 -  
22 -/**  
23 - * 数据过滤处理  
24 - *  
25 - * @author ruoyi  
26 - */  
27 -@Aspect  
28 -@Component  
29 -public class DataScopeAspect {  
30 - /**  
31 - * 全部数据权限  
32 - */  
33 - public static final String DATA_SCOPE_ALL = "1";  
34 -  
35 - /**  
36 - * 自定数据权限  
37 - */  
38 - public static final String DATA_SCOPE_CUSTOM = "2";  
39 -  
40 - /**  
41 - * 部门数据权限  
42 - */  
43 - public static final String DATA_SCOPE_DEPT = "3";  
44 -  
45 - /**  
46 - * 部门及以下数据权限  
47 - */  
48 - public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";  
49 -  
50 - /**  
51 - * 仅本人数据权限  
52 - */  
53 - public static final String DATA_SCOPE_SELF = "5";  
54 -  
55 - /**  
56 - * 数据权限过滤关键字  
57 - */  
58 - public static final String DATA_SCOPE = "dataScope";  
59 -  
60 - // 配置织入点  
61 - @Pointcut("@annotation(com.ruoyi.common.annotation.DataScope)")  
62 - public void dataScopePointCut() {  
63 - }  
64 -  
65 - @Before("dataScopePointCut()")  
66 - public void doBefore(JoinPoint point) throws Throwable {  
67 - handleDataScope(point);  
68 - }  
69 -  
70 - protected void handleDataScope(final JoinPoint joinPoint) {  
71 - // 获得注解  
72 - DataScope controllerDataScope = getAnnotationLog(joinPoint);  
73 - if (controllerDataScope == null) {  
74 - return;  
75 - }  
76 - // 获取当前的用户  
77 - LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());  
78 - if (StringUtils.isNotNull(loginUser)) {  
79 - SysUser currentUser = loginUser.getUser();  
80 - // 如果是超级管理员,则不过滤数据  
81 - if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) {  
82 - dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),  
83 - controllerDataScope.userAlias());  
84 - }  
85 - }  
86 - }  
87 -  
88 - /**  
89 - * 数据范围过滤  
90 - *  
91 - * @param joinPoint 切点  
92 - * @param user 用户  
93 - * @param userAlias 别名  
94 - */  
95 - public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias) {  
96 - StringBuilder sqlString = new StringBuilder();  
97 -  
98 - for (SysRole role : user.getRoles()) {  
99 - String dataScope = role.getDataScope();  
100 - if (DATA_SCOPE_ALL.equals(dataScope)) {  
101 - sqlString = new StringBuilder();  
102 - break;  
103 - } else if (DATA_SCOPE_CUSTOM.equals(dataScope)) {  
104 - sqlString.append(StringUtils.format(  
105 - " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,  
106 - role.getRoleId()));  
107 - } else if (DATA_SCOPE_DEPT.equals(dataScope)) {  
108 - sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));  
109 - } else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) {  
110 - sqlString.append(StringUtils.format(  
111 - " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",  
112 - deptAlias, user.getDeptId(), user.getDeptId()));  
113 - } else if (DATA_SCOPE_SELF.equals(dataScope)) {  
114 - if (StringUtils.isNotBlank(userAlias)) {  
115 - sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));  
116 - } else {  
117 - // 数据权限为仅本人且没有userAlias别名不查询任何数据  
118 - sqlString.append(" OR 1=0 ");  
119 - }  
120 - }  
121 - }  
122 -  
123 - if (StringUtils.isNotBlank(sqlString.toString())) {  
124 - Object params = joinPoint.getArgs()[0];  
125 - if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {  
126 - BaseEntity baseEntity = (BaseEntity) params;  
127 - baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");  
128 - }  
129 - }  
130 - }  
131 -  
132 - /**  
133 - * 是否存在注解,如果存在就获取  
134 - */  
135 - private DataScope getAnnotationLog(JoinPoint joinPoint) {  
136 - Signature signature = joinPoint.getSignature();  
137 - MethodSignature methodSignature = (MethodSignature) signature;  
138 - Method method = methodSignature.getMethod();  
139 -  
140 - if (method != null) {  
141 - return method.getAnnotation(DataScope.class);  
142 - }  
143 - return null;  
144 - }  
145 -}  
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataSource.java deleted
1 -package com.ruoyi.common.annotation;  
2 -  
3 -import java.lang.annotation.Documented;  
4 -import java.lang.annotation.ElementType;  
5 -import java.lang.annotation.Inherited;  
6 -import java.lang.annotation.Retention;  
7 -import java.lang.annotation.RetentionPolicy;  
8 -import java.lang.annotation.Target;  
9 -  
10 -import com.ruoyi.common.enums.DataSourceType;  
11 -  
12 -/**  
13 - * 自定义多数据源切换注解  
14 - * <p>  
15 - * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准  
16 - *  
17 - * @author ruoyi  
18 - */  
19 -@Target({ElementType.METHOD, ElementType.TYPE})  
20 -@Retention(RetentionPolicy.RUNTIME)  
21 -@Documented  
22 -@Inherited  
23 -public @interface DataSource {  
24 - /**  
25 - * 切换数据源名称  
26 - */  
27 - public DataSourceType value() default DataSourceType.MASTER;  
28 -}  
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataSourceAspect.java deleted
1 -package com.ruoyi.framework.aspectj;  
2 -  
3 -import java.util.Objects;  
4 -  
5 -import org.aspectj.lang.ProceedingJoinPoint;  
6 -import org.aspectj.lang.annotation.Around;  
7 -import org.aspectj.lang.annotation.Aspect;  
8 -import org.aspectj.lang.annotation.Pointcut;  
9 -import org.aspectj.lang.reflect.MethodSignature;  
10 -import org.slf4j.Logger;  
11 -import org.slf4j.LoggerFactory;  
12 -import org.springframework.core.annotation.AnnotationUtils;  
13 -import org.springframework.core.annotation.Order;  
14 -import org.springframework.stereotype.Component;  
15 -import com.ruoyi.common.annotation.DataSource;  
16 -import com.ruoyi.common.utils.StringUtils;  
17 -import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder;  
18 -  
19 -/**  
20 - * 多数据源处理  
21 - *  
22 - * @author ruoyi  
23 - */  
24 -@Aspect  
25 -@Order(1)  
26 -@Component  
27 -public class DataSourceAspect {  
28 - protected Logger logger = LoggerFactory.getLogger(getClass());  
29 -  
30 - @Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)"  
31 - + "|| @within(com.ruoyi.common.annotation.DataSource)")  
32 - public void dsPointCut() {  
33 -  
34 - }  
35 -  
36 - @Around("dsPointCut()")  
37 - public Object around(ProceedingJoinPoint point) throws Throwable {  
38 - DataSource dataSource = getDataSource(point);  
39 -  
40 - if (StringUtils.isNotNull(dataSource)) {  
41 - DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());  
42 - }  
43 -  
44 - try {  
45 - return point.proceed();  
46 - } finally {  
47 - // 销毁数据源 在执行方法之后  
48 - DynamicDataSourceContextHolder.clearDataSourceType();  
49 - }  
50 - }  
51 -  
52 - /**  
53 - * 获取需要切换的数据源  
54 - */  
55 - public DataSource getDataSource(ProceedingJoinPoint point) {  
56 - MethodSignature signature = (MethodSignature) point.getSignature();  
57 - DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);  
58 - if (Objects.nonNull(dataSource)) {  
59 - return dataSource;  
60 - }  
61 -  
62 - return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);  
63 - }  
64 -}  
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataSourceType.java deleted
1 -package com.ruoyi.common.enums;  
2 -  
3 -/**  
4 - * 数据源  
5 - *  
6 - * @author ruoyi  
7 - */  
8 -public enum DataSourceType  
9 -{  
10 - /**  
11 - * 主库  
12 - */  
13 - MASTER,  
14 -  
15 - /**  
16 - * 从库  
17 - */  
18 - SLAVE  
19 -}  
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DynamicDataSource.java deleted
1 -package com.ruoyi.framework.datasource;  
2 -  
3 -import java.util.Map;  
4 -import javax.sql.DataSource;  
5 -  
6 -import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;  
7 -  
8 -/**  
9 - * 动态数据源  
10 - *  
11 - * @author ruoyi  
12 - */  
13 -public class DynamicDataSource extends AbstractRoutingDataSource {  
14 - public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {  
15 - super.setDefaultTargetDataSource(defaultTargetDataSource);  
16 - super.setTargetDataSources(targetDataSources);  
17 - super.afterPropertiesSet();  
18 - }  
19 -  
20 - @Override  
21 - protected Object determineCurrentLookupKey() {  
22 - return DynamicDataSourceContextHolder.getDataSourceType();  
23 - }  
24 -}  
ruoyi-common/src/main/java/com/ruoyi/common/annotation/DynamicDataSourceContextHolder.java deleted
1 -package com.ruoyi.framework.datasource;  
2 -  
3 -import org.slf4j.Logger;  
4 -import org.slf4j.LoggerFactory;  
5 -  
6 -/**  
7 - * 数据源切换处理  
8 - *  
9 - * @author ruoyi  
10 - */  
11 -public class DynamicDataSourceContextHolder {  
12 - public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);  
13 -  
14 - /**  
15 - * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,  
16 - * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。  
17 - */  
18 - private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();  
19 -  
20 - /**  
21 - * 设置数据源的变量  
22 - */  
23 - public static void setDataSourceType(String dsType) {  
24 - log.info("切换到{}数据源", dsType);  
25 - CONTEXT_HOLDER.set(dsType);  
26 - }  
27 -  
28 - /**  
29 - * 获得数据源的变量  
30 - */  
31 - public static String getDataSourceType() {  
32 - return CONTEXT_HOLDER.get();  
33 - }  
34 -  
35 - /**  
36 - * 清空数据源变量  
37 - */  
38 - public static void clearDataSourceType() {  
39 - CONTEXT_HOLDER.remove();  
40 - }  
41 -}  
ruoyi-common/src/main/java/com/ruoyi/common/config/DruidConfig.java deleted
1 -package com.ruoyi.framework.config;  
2 -  
3 -import java.io.IOException;  
4 -import java.util.HashMap;  
5 -import java.util.Map;  
6 -import javax.servlet.Filter;  
7 -import javax.servlet.FilterChain;  
8 -import javax.servlet.ServletException;  
9 -import javax.servlet.ServletRequest;  
10 -import javax.servlet.ServletResponse;  
11 -import javax.sql.DataSource;  
12 -  
13 -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
14 -import org.springframework.boot.context.properties.ConfigurationProperties;  
15 -import org.springframework.boot.web.servlet.FilterRegistrationBean;  
16 -import org.springframework.context.annotation.Bean;  
17 -import org.springframework.context.annotation.Configuration;  
18 -import org.springframework.context.annotation.Primary;  
19 -import com.alibaba.druid.pool.DruidDataSource;  
20 -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;  
21 -import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;  
22 -import com.alibaba.druid.util.Utils;  
23 -import com.ruoyi.common.enums.DataSourceType;  
24 -import com.ruoyi.common.utils.spring.SpringUtils;  
25 -import com.ruoyi.framework.config.properties.DruidProperties;  
26 -import com.ruoyi.framework.datasource.DynamicDataSource;  
27 -  
28 -/**  
29 - * druid 配置多数据源  
30 - *  
31 - * @author ruoyi  
32 - */  
33 -@Configuration  
34 -public class DruidConfig {  
35 - @Bean  
36 - @ConfigurationProperties("spring.datasource.druid.master")  
37 - public DataSource masterDataSource(DruidProperties druidProperties) {  
38 - DruidDataSource dataSource = DruidDataSourceBuilder.create().build();  
39 - return druidProperties.dataSource(dataSource);  
40 - }  
41 -  
42 - @Bean  
43 - @ConfigurationProperties("spring.datasource.druid.slave")  
44 - @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")  
45 - public DataSource slaveDataSource(DruidProperties druidProperties) {  
46 - DruidDataSource dataSource = DruidDataSourceBuilder.create().build();  
47 - return druidProperties.dataSource(dataSource);  
48 - }  
49 -  
50 - @Bean(name = "dynamicDataSource")  
51 - @Primary  
52 - public DynamicDataSource dataSource(DataSource masterDataSource) {  
53 - Map<Object, Object> targetDataSources = new HashMap<>();  
54 - targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);  
55 - setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");  
56 - return new DynamicDataSource(masterDataSource, targetDataSources);  
57 - }  
58 -  
59 - /**  
60 - * 设置数据源  
61 - *  
62 - * @param targetDataSources 备选数据源集合  
63 - * @param sourceName 数据源名称  
64 - * @param beanName bean名称  
65 - */  
66 - public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName) {  
67 - try {  
68 - DataSource dataSource = SpringUtils.getBean(beanName);  
69 - targetDataSources.put(sourceName, dataSource);  
70 - } catch (Exception e) {  
71 - }  
72 - }  
73 -  
74 - /**  
75 - * 去除监控页面底部的广告  
76 - */  
77 - @SuppressWarnings({"rawtypes", "unchecked"})  
78 - @Bean  
79 - @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")  
80 - public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) {  
81 - // 获取web监控页面的参数  
82 - DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();  
83 - // 提取common.js的配置路径  
84 - String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";  
85 - String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");  
86 - final String filePath = "support/http/resources/js/common.js";  
87 - // 创建filter进行过滤  
88 - Filter filter = new Filter() {  
89 - @Override  
90 - public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {  
91 - }  
92 -  
93 - @Override  
94 - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  
95 - throws IOException, ServletException {  
96 - chain.doFilter(request, response);  
97 - // 重置缓冲区,响应头不会被重置  
98 - response.resetBuffer();  
99 - // 获取common.js  
100 - String text = Utils.readFromResource(filePath);  
101 - // 正则替换banner, 除去底部的广告信息  
102 - text = text.replaceAll("<a.*?banner\"></a><br/>", "");  
103 - text = text.replaceAll("powered.*?shrek.wang</a>", "");  
104 - response.getWriter().write(text);  
105 - }  
106 -  
107 - @Override  
108 - public void destroy() {  
109 - }  
110 - };  
111 - FilterRegistrationBean registrationBean = new FilterRegistrationBean();  
112 - registrationBean.setFilter(filter);  
113 - registrationBean.addUrlPatterns(commonJsPattern);  
114 - return registrationBean;  
115 - }  
116 -}  
ruoyi-common/src/main/resources/application-druid.yml deleted
1 -# 数据源配置  
2 -spring:  
3 - datasource:  
4 - type: com.alibaba.druid.pool.DruidDataSource  
5 - driverClassName: com.mysql.cj.jdbc.Driver  
6 - druid:  
7 - # 主库数据源  
8 - master:  
9 - url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8  
10 - username: root  
11 - password: password  
12 - # 从库数据源  
13 - slave:  
14 - # 从数据源开关/默认关闭  
15 - enabled: false  
16 - url:  
17 - username:  
18 - password:  
19 - # 初始连接数  
20 - initialSize: 5  
21 - # 最小连接池数量  
22 - minIdle: 10  
23 - # 最大连接池数量  
24 - maxActive: 20  
25 - # 配置获取连接等待超时的时间  
26 - maxWait: 60000  
27 - # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒  
28 - timeBetweenEvictionRunsMillis: 60000  
29 - # 配置一个连接在池中最小生存的时间,单位是毫秒  
30 - minEvictableIdleTimeMillis: 300000  
31 - # 配置一个连接在池中最大生存的时间,单位是毫秒  
32 - maxEvictableIdleTimeMillis: 900000  
33 - # 配置检测连接是否有效  
34 - validationQuery: SELECT 1 FROM DUAL  
35 - testWhileIdle: true  
36 - testOnBorrow: false  
37 - testOnReturn: false  
src/main/java/cn/iocoder/dashboard/framework/datasource/config/DataSourceConfiguration.java
1 package cn.iocoder.dashboard.framework.datasource.config; 1 package cn.iocoder.dashboard.framework.datasource.config;
2 2
  3 +import cn.iocoder.dashboard.framework.datasource.core.filter.DruidAdRemoveFilter;
  4 +import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
  5 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  6 +import org.springframework.boot.web.servlet.FilterRegistrationBean;
  7 +import org.springframework.context.annotation.Bean;
3 import org.springframework.context.annotation.Configuration; 8 import org.springframework.context.annotation.Configuration;
4 import org.springframework.transaction.annotation.EnableTransactionManagement; 9 import org.springframework.transaction.annotation.EnableTransactionManagement;
5 10
6 /** 11 /**
7 - * 数据库匹配类 12 + * 数据库配置类
  13 + *
  14 + * @author 芋道源码
8 */ 15 */
9 @Configuration 16 @Configuration
10 @EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理 17 @EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理
11 public class DataSourceConfiguration { 18 public class DataSourceConfiguration {
  19 +
  20 + /**
  21 + * 创建 DruidAdRemoveFilter 过滤器,过滤 common.js 的广告
  22 + */
  23 + @Bean
  24 + @ConditionalOnProperty(name = "spring.datasource.druid.web-stat-filter.enabled", havingValue = "true")
  25 + public FilterRegistrationBean<DruidAdRemoveFilter> druidAdRemoveFilterFilter(DruidStatProperties properties) {
  26 + // 获取 druid web 监控页面的参数
  27 + DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
  28 + // 提取 common.js 的配置路径
  29 + String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
  30 + String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
  31 + // 创建 DruidAdRemoveFilter Bean
  32 + FilterRegistrationBean<DruidAdRemoveFilter> registrationBean = new FilterRegistrationBean<>();
  33 + registrationBean.setFilter(new DruidAdRemoveFilter());
  34 + registrationBean.addUrlPatterns(commonJsPattern);
  35 + return registrationBean;
  36 + }
  37 +
12 } 38 }
src/main/java/cn/iocoder/dashboard/framework/datasource/core/enums/DataSourceEnum.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.datasource.core.enums;
  2 +
  3 +/**
  4 + * 对应于多数据源中不同数据源配置
  5 + *
  6 + * 通过在方法上,使用 {@link com.baomidou.dynamic.datasource.annotation.DS} 注解,设置使用的数据源。
  7 + * 注意,默认是 {@link #MASTER} 数据源
  8 + *
  9 + * 对应官方文档为 http://dynamic-datasource.com/guide/customize/Annotation.html
  10 + */
  11 +public interface DataSourceEnum {
  12 +
  13 + /**
  14 + * 主库,推荐使用 {@link com.baomidou.dynamic.datasource.annotation.Master} 注解
  15 + */
  16 + String MASTER = "master";
  17 + /**
  18 + * 从库,推荐使用 {@link com.baomidou.dynamic.datasource.annotation.Slave} 注解
  19 + */
  20 + String SLAVE = "slave";
  21 +
  22 +}
src/main/java/cn/iocoder/dashboard/framework/datasource/core/filter/DruidAdRemoveFilter.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.datasource.core.filter;
  2 +
  3 +import com.alibaba.druid.util.Utils;
  4 +import org.springframework.web.filter.OncePerRequestFilter;
  5 +
  6 +import javax.servlet.FilterChain;
  7 +import javax.servlet.ServletException;
  8 +import javax.servlet.http.HttpServletRequest;
  9 +import javax.servlet.http.HttpServletResponse;
  10 +import java.io.IOException;
  11 +
  12 +/**
  13 + * Druid 底部广告过滤器
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +public class DruidAdRemoveFilter extends OncePerRequestFilter {
  18 +
  19 + /**
  20 + * common.js 的路径
  21 + */
  22 + private static final String COMMON_JS_ILE_PATH = "support/http/resources/js/common.js";
  23 +
  24 + @Override
  25 + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
  26 + throws ServletException, IOException {
  27 + chain.doFilter(request, response);
  28 + // 重置缓冲区,响应头不会被重置
  29 + response.resetBuffer();
  30 + // 获取 common.js
  31 + String text = Utils.readFromResource(COMMON_JS_ILE_PATH);
  32 + // 正则替换 banner, 除去底部的广告信息
  33 + text = text.replaceAll("<a.*?banner\"></a><br/>", "");
  34 + text = text.replaceAll("powered.*?shrek.wang</a>", "");
  35 + response.getWriter().write(text);
  36 + }
  37 +
  38 +}
src/main/java/cn/iocoder/dashboard/modules/tool/dal/mysql/codegen/ToolSchemaTableMapper.java
@@ -18,11 +18,7 @@ public interface ToolSchemaTableMapper extends BaseMapperX&lt;ToolSchemaTableDO&gt; { @@ -18,11 +18,7 @@ public interface ToolSchemaTableMapper extends BaseMapperX&lt;ToolSchemaTableDO&gt; {
18 .likeIfPresent("table_comment", tableComment)); 18 .likeIfPresent("table_comment", tableComment));
19 } 19 }
20 20
21 - default List<ToolSchemaTableDO> selectListByTableSchema(String tableSchema) {  
22 - return selectList(new QueryWrapper<ToolSchemaTableDO>().eq("table_schema", tableSchema));  
23 - }  
24 -  
25 - default ToolSchemaTableDO selectByTableName1(String tableSchema, String tableName) { 21 + default ToolSchemaTableDO selectByTableSchemaAndTableName(String tableSchema, String tableName) {
26 return selectOne(new QueryWrapper<ToolSchemaTableDO>().eq("table_schema",tableSchema) 22 return selectOne(new QueryWrapper<ToolSchemaTableDO>().eq("table_schema",tableSchema)
27 .eq("table_name", tableName)); 23 .eq("table_name", tableName));
28 } 24 }
src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenServiceImpl.java
@@ -101,10 +101,10 @@ public class ToolCodegenServiceImpl implements ToolCodegenService { @@ -101,10 +101,10 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
101 101
102 @Override 102 @Override
103 public Long createCodegen(String tableName) { 103 public Long createCodegen(String tableName) {
104 - //获取当前schema 104 + // 获取当前schema
105 String tableSchema = codegenProperties.getDbSchemas().iterator().next(); 105 String tableSchema = codegenProperties.getDbSchemas().iterator().next();
106 // 从数据库中,获得数据库表结构 106 // 从数据库中,获得数据库表结构
107 - ToolSchemaTableDO schemaTable = schemaTableMapper.selectByTableName1(tableSchema, tableName); 107 + ToolSchemaTableDO schemaTable = schemaTableMapper.selectByTableSchemaAndTableName(tableSchema, tableName);
108 List<ToolSchemaColumnDO> schemaColumns = schemaColumnMapper.selectListByTableName(tableSchema, tableName); 108 List<ToolSchemaColumnDO> schemaColumns = schemaColumnMapper.selectListByTableName(tableSchema, tableName);
109 // 导入 109 // 导入
110 return this.createCodegen0(ToolCodegenImportTypeEnum.DB, schemaTable, schemaColumns); 110 return this.createCodegen0(ToolCodegenImportTypeEnum.DB, schemaTable, schemaColumns);
src/main/resources/application-dev.yaml
@@ -4,34 +4,56 @@ server: @@ -4,34 +4,56 @@ server:
4 --- #################### 数据库相关配置 #################### 4 --- #################### 数据库相关配置 ####################
5 5
6 spring: 6 spring:
7 - # 数据源配置项 TODO 多数据源;TODO 监控配置 7 + # 数据源配置项
  8 + autoconfigure:
  9 + exclude:
  10 + - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
8 datasource: 11 datasource:
9 - name: ruoyi-vue-pro  
10 - url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT  
11 - driver-class-name: com.mysql.jdbc.Driver  
12 - username: root  
13 - password: 3WLiVUBEwTbvAfsh  
14 - druid: 12 + druid: # Druid 【监控】相关的全局配置
15 web-stat-filter: 13 web-stat-filter:
16 enabled: true 14 enabled: true
17 stat-view-servlet: 15 stat-view-servlet:
18 enabled: true 16 enabled: true
19 - # 设置白名单,不填则允许所有访问  
20 - allow: 17 + allow: # 设置白名单,不填则允许所有访问
21 url-pattern: /druid/* 18 url-pattern: /druid/*
22 - # 控制台管理用户名和密码  
23 - login-username: 19 + login-username: # 控制台管理用户名和密码
24 login-password: 20 login-password:
25 filter: 21 filter:
26 stat: 22 stat:
27 enabled: true 23 enabled: true
28 - # 慢 SQL 记录  
29 - log-slow-sql: true 24 + log-slow-sql: true # 慢 SQL 记录
30 slow-sql-millis: 100 25 slow-sql-millis: 100
31 merge-sql: true 26 merge-sql: true
32 wall: 27 wall:
33 config: 28 config:
34 multi-statement-allow: true 29 multi-statement-allow: true
  30 + dynamic: # 多数据源配置
  31 + druid: # Druid 【连接池】相关的全局配置
  32 + initial-size: 5 # 初始连接数
  33 + min-idle: 10 # 最小连接池数量
  34 + max-active: 20 # 最大连接池数量
  35 + max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
  36 + time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
  37 + min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
  38 + max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
  39 + validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
  40 + test-while-idle: true
  41 + test-on-borrow: false
  42 + test-on-return: false
  43 + primary: master
  44 + datasource:
  45 + master:
  46 + name: ruoyi-vue-pro
  47 + url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
  48 + driver-class-name: com.mysql.jdbc.Driver
  49 + username: root
  50 + password: 3WLiVUBEwTbvAfsh
  51 + slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
  52 + name: ruoyi-vue-pro
  53 + url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
  54 + driver-class-name: com.mysql.jdbc.Driver
  55 + username: root
  56 + password: 3WLiVUBEwTbvAfsh
35 57
36 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 58 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
37 redis: 59 redis:
@@ -77,9 +99,9 @@ apollo: @@ -77,9 +99,9 @@ apollo:
77 eagerLoad: 99 eagerLoad:
78 enabled: true # 设置 Apollo 在日志初始化前生效,可以实现日志的动态级别配置 100 enabled: true # 设置 Apollo 在日志初始化前生效,可以实现日志的动态级别配置
79 jdbc: # 自定义的 JDBC 配置项,用于数据库的地址 101 jdbc: # 自定义的 JDBC 配置项,用于数据库的地址
80 - url: ${spring.datasource.url}  
81 - username: ${spring.datasource.username}  
82 - password: ${spring.datasource.password} 102 + url: ${spring.datasource.dynamic.datasource.master.url}
  103 + username: ${spring.datasource.dynamic.datasource.master.username}
  104 + password: ${spring.datasource.dynamic.datasource.master.password}
83 105
84 --- #################### 服务保障相关配置 #################### 106 --- #################### 服务保障相关配置 ####################
85 107
@@ -155,7 +177,7 @@ yudao: @@ -155,7 +177,7 @@ yudao:
155 base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/system/file/get/ 177 base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/system/file/get/
156 codegen: 178 codegen:
157 base-package: ${yudao.info.base-package} 179 base-package: ${yudao.info.base-package}
158 - db-schemas: ${spring.datasource.name} 180 + db-schemas: ${spring.datasource.dynamic.datasource.master.name}
159 xss: 181 xss:
160 enable: false 182 enable: false
161 exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 183 exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
src/main/resources/application-local.yaml
@@ -4,34 +4,56 @@ server: @@ -4,34 +4,56 @@ server:
4 --- #################### 数据库相关配置 #################### 4 --- #################### 数据库相关配置 ####################
5 5
6 spring: 6 spring:
7 - # 数据源配置项 TODO 多数据源;TODO 监控配置 7 + # 数据源配置项
  8 + autoconfigure:
  9 + exclude:
  10 + - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
8 datasource: 11 datasource:
9 - name: ruoyi-vue-pro  
10 - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT  
11 - driver-class-name: com.mysql.jdbc.Driver  
12 - username: root  
13 - password: 123456  
14 - druid: 12 + druid: # Druid 【监控】相关的全局配置
15 web-stat-filter: 13 web-stat-filter:
16 enabled: true 14 enabled: true
17 stat-view-servlet: 15 stat-view-servlet:
18 enabled: true 16 enabled: true
19 - # 设置白名单,不填则允许所有访问  
20 - allow: 17 + allow: # 设置白名单,不填则允许所有访问
21 url-pattern: /druid/* 18 url-pattern: /druid/*
22 - # 控制台管理用户名和密码  
23 - login-username: 19 + login-username: # 控制台管理用户名和密码
24 login-password: 20 login-password:
25 filter: 21 filter:
26 stat: 22 stat:
27 enabled: true 23 enabled: true
28 - # 慢 SQL 记录  
29 - log-slow-sql: true 24 + log-slow-sql: true # 慢 SQL 记录
30 slow-sql-millis: 100 25 slow-sql-millis: 100
31 merge-sql: true 26 merge-sql: true
32 wall: 27 wall:
33 config: 28 config:
34 multi-statement-allow: true 29 multi-statement-allow: true
  30 + dynamic: # 多数据源配置
  31 + druid: # Druid 【连接池】相关的全局配置
  32 + initial-size: 5 # 初始连接数
  33 + min-idle: 10 # 最小连接池数量
  34 + max-active: 20 # 最大连接池数量
  35 + max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
  36 + time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
  37 + min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
  38 + max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
  39 + validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
  40 + test-while-idle: true
  41 + test-on-borrow: false
  42 + test-on-return: false
  43 + primary: master
  44 + datasource:
  45 + master:
  46 + name: ruoyi-vue-pro
  47 + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
  48 + driver-class-name: com.mysql.jdbc.Driver
  49 + username: root
  50 + password: 123456
  51 + slave: # 模拟从库,可根据自己需要修改
  52 + name: ruoyi-vue-pro
  53 + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
  54 + driver-class-name: com.mysql.jdbc.Driver
  55 + username: root
  56 + password: 123456
35 57
36 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 58 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
37 redis: 59 redis:
@@ -77,9 +99,9 @@ apollo: @@ -77,9 +99,9 @@ apollo:
77 eagerLoad: 99 eagerLoad:
78 enabled: true # 设置 Apollo 在日志初始化前生效,可以实现日志的动态级别配置 100 enabled: true # 设置 Apollo 在日志初始化前生效,可以实现日志的动态级别配置
79 jdbc: # 自定义的 JDBC 配置项,用于数据库的地址 101 jdbc: # 自定义的 JDBC 配置项,用于数据库的地址
80 - url: ${spring.datasource.url}  
81 - username: ${spring.datasource.username}  
82 - password: ${spring.datasource.password} 102 + url: ${spring.datasource.dynamic.datasource.master.url}
  103 + username: ${spring.datasource.dynamic.datasource.master.username}
  104 + password: ${spring.datasource.dynamic.datasource.master.password}
83 105
84 --- #################### 服务保障相关配置 #################### 106 --- #################### 服务保障相关配置 ####################
85 107
@@ -155,7 +177,7 @@ yudao: @@ -155,7 +177,7 @@ yudao:
155 base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/system/file/get/ 177 base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/system/file/get/
156 codegen: 178 codegen:
157 base-package: ${yudao.info.base-package} 179 base-package: ${yudao.info.base-package}
158 - db-schemas: ${spring.datasource.name} 180 + db-schemas: ${spring.datasource.dynamic.datasource.master.name}
159 xss: 181 xss:
160 enable: false 182 enable: false
161 exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 183 exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
src/main/resources/application.yaml
@@ -12,7 +12,6 @@ spring: @@ -12,7 +12,6 @@ spring:
12 max-file-size: 16MB # 单个文件大小 12 max-file-size: 16MB # 单个文件大小
13 max-request-size: 32MB # 设置总上传的文件大小 13 max-request-size: 32MB # 设置总上传的文件大小
14 14
15 - # Jackson 配置项  
16 jackson: 15 jackson:
17 serialization: 16 serialization:
18 write-dates-as-timestamps: true # 设置 Date 的格式,使用时间戳 17 write-dates-as-timestamps: true # 设置 Date 的格式,使用时间戳
@@ -32,3 +31,6 @@ mybatis-plus: @@ -32,3 +31,6 @@ mybatis-plus:
32 logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) 31 logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
33 mapper-locations: classpath*:mapper/*.xml 32 mapper-locations: classpath*:mapper/*.xml
34 type-aliases-package: ${yudao.info.base-package}.modules.*.dal.dataobject 33 type-aliases-package: ${yudao.info.base-package}.modules.*.dal.dataobject
  34 +
  35 +--- #################### 芋道相关配置 ####################
  36 +
src/test-integration/java/cn/iocoder/dashboard/BaseDbAndRedisIntegrationTest.java
@@ -3,7 +3,7 @@ package cn.iocoder.dashboard; @@ -3,7 +3,7 @@ package cn.iocoder.dashboard;
3 import cn.iocoder.dashboard.framework.datasource.config.DataSourceConfiguration; 3 import cn.iocoder.dashboard.framework.datasource.config.DataSourceConfiguration;
4 import cn.iocoder.dashboard.framework.mybatis.config.MybatisConfiguration; 4 import cn.iocoder.dashboard.framework.mybatis.config.MybatisConfiguration;
5 import cn.iocoder.dashboard.framework.redis.config.RedisConfig; 5 import cn.iocoder.dashboard.framework.redis.config.RedisConfig;
6 -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; 6 +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
7 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; 7 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
8 import org.redisson.spring.starter.RedissonAutoConfiguration; 8 import org.redisson.spring.starter.RedissonAutoConfiguration;
9 import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; 9 import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
@@ -19,13 +19,14 @@ public class BaseDbAndRedisIntegrationTest { @@ -19,13 +19,14 @@ public class BaseDbAndRedisIntegrationTest {
19 19
20 @Import({ 20 @Import({
21 // DB 配置类 21 // DB 配置类
  22 + DynamicDataSourceAutoConfiguration.class, // Dynamic Datasource 配置类
22 DataSourceConfiguration.class, // 自己的 DB 配置类 23 DataSourceConfiguration.class, // 自己的 DB 配置类
23 DataSourceAutoConfiguration.class, // Spring DB 自动配置类 24 DataSourceAutoConfiguration.class, // Spring DB 自动配置类
24 DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 25 DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
25 - DruidDataSourceAutoConfigure.class, // Druid 自动配置类  
26 // MyBatis 配置类 26 // MyBatis 配置类
27 MybatisConfiguration.class, // 自己的 MyBatis 配置类 27 MybatisConfiguration.class, // 自己的 MyBatis 配置类
28 MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类 28 MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
  29 +
29 // Redis 配置类 30 // Redis 配置类
30 RedisAutoConfiguration.class, // Spring Redis 自动配置类 31 RedisAutoConfiguration.class, // Spring Redis 自动配置类
31 RedisConfig.class, // 自己的 Redis 配置类 32 RedisConfig.class, // 自己的 Redis 配置类
src/test-integration/java/cn/iocoder/dashboard/modules/tool/dal/mysql/codegen/ToolInformationSchemaTableMapperTest.java
1 package cn.iocoder.dashboard.modules.tool.dal.mysql.codegen; 1 package cn.iocoder.dashboard.modules.tool.dal.mysql.codegen;
2 2
3 import cn.iocoder.dashboard.BaseDbUnitTest; 3 import cn.iocoder.dashboard.BaseDbUnitTest;
4 -import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolSchemaTableDO;  
5 -import org.junit.jupiter.api.Test;  
6 4
7 import javax.annotation.Resource; 5 import javax.annotation.Resource;
8 -import java.util.List;  
9 -  
10 -import static org.junit.jupiter.api.Assertions.assertTrue;  
11 6
12 class ToolInformationSchemaTableMapperTest extends BaseDbUnitTest { 7 class ToolInformationSchemaTableMapperTest extends BaseDbUnitTest {
13 8
14 @Resource 9 @Resource
15 private ToolSchemaTableMapper toolInformationSchemaTableMapper; 10 private ToolSchemaTableMapper toolInformationSchemaTableMapper;
16 11
17 - @Test  
18 - public void tstSelectListByTableSchema() {  
19 - List<ToolSchemaTableDO> tables = toolInformationSchemaTableMapper  
20 - .selectListByTableSchema("ruoyi-vue-pro");  
21 - assertTrue(tables.size() > 0);  
22 - }  
23 -  
24 } 12 }
src/test-integration/resources/application-integration-test.yaml
@@ -7,12 +7,55 @@ spring: @@ -7,12 +7,55 @@ spring:
7 7
8 spring: 8 spring:
9 # 数据源配置项 9 # 数据源配置项
  10 + autoconfigure:
  11 + exclude:
  12 + - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
10 datasource: 13 datasource:
11 - name: ruoyi-vue-pro  
12 - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT  
13 - driver-class-name: com.mysql.jdbc.Driver  
14 - username: root  
15 - password: 123456 14 + druid: # Druid 【监控】相关的全局配置
  15 + web-stat-filter:
  16 + enabled: true
  17 + stat-view-servlet:
  18 + enabled: true
  19 + allow: # 设置白名单,不填则允许所有访问
  20 + url-pattern: /druid/*
  21 + login-username: # 控制台管理用户名和密码
  22 + login-password:
  23 + filter:
  24 + stat:
  25 + enabled: true
  26 + log-slow-sql: true # 慢 SQL 记录
  27 + slow-sql-millis: 100
  28 + merge-sql: true
  29 + wall:
  30 + config:
  31 + multi-statement-allow: true
  32 + dynamic: # 多数据源配置
  33 + druid: # Druid 【连接池】相关的全局配置
  34 + initial-size: 5 # 初始连接数
  35 + min-idle: 10 # 最小连接池数量
  36 + max-active: 20 # 最大连接池数量
  37 + max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
  38 + time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
  39 + min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
  40 + max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
  41 + validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
  42 + test-while-idle: true
  43 + test-on-borrow: false
  44 + test-on-return: false
  45 + primary: master
  46 + datasource:
  47 + master:
  48 + name: ruoyi-vue-pro
  49 + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
  50 + driver-class-name: com.mysql.jdbc.Driver
  51 + username: root
  52 + password: 123456
  53 + slave: # 模拟从库,可根据自己需要修改
  54 + name: ruoyi-vue-pro
  55 + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
  56 + driver-class-name: com.mysql.jdbc.Driver
  57 + username: root
  58 + password: 123456
16 59
17 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 60 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
18 redis: 61 redis:
@@ -70,7 +113,7 @@ yudao: @@ -70,7 +113,7 @@ yudao:
70 base-path: http://127.0.0.1:${server.port}/${yudao.web.api-prefix}/file/get/ 113 base-path: http://127.0.0.1:${server.port}/${yudao.web.api-prefix}/file/get/
71 codegen: 114 codegen:
72 base-package: ${yudao.info.base-package}.modules 115 base-package: ${yudao.info.base-package}.modules
73 - db-schemas: ${spring.datasource.name} 116 + db-schemas: ${spring.datasource.dynamic.datasource.master.name}
74 xss: 117 xss:
75 enable: false 118 enable: false
76 exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 119 exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系