From 50d9199f5344c41e4b593d14f374b0a71d511771 Mon Sep 17 00:00:00 2001 From: Dftre <3066417822@qq.com> Date: Thu, 9 Jan 2025 23:42:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddruid=E7=9A=84sql=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E5=92=8Csql=E9=98=B2=E7=81=AB=E5=A2=99=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E6=9A=82=E6=97=B6=E5=85=B3=E9=97=AD=E5=88=86=E5=B8=83?= =?UTF-8?q?=E5=BC=8F=E4=BA=8B=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-druid.yml | 24 ++++++++++--- .../framework/aspectj/DataScopeAspect.java | 2 +- .../ruoyi/framework/config/DruidConfig.java | 26 ++++++++++++++ .../config/DynamicDataSourceProperties.java | 34 ++++++++++++++++++- .../datasource/DataSourceCreate.java | 16 +++++++-- ruoyi-plugins/ruoyi-plugins-starter/pom.xml | 4 +-- 6 files changed, 96 insertions(+), 10 deletions(-) diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml index 8657312..740b4fc 100644 --- a/ruoyi-admin/src/main/resources/application-druid.yml +++ b/ruoyi-admin/src/main/resources/application-druid.yml @@ -15,6 +15,8 @@ spring: # url: jdbc:postgresql://127.0.0.1/ry # username: postgres # password: 123456 + # filters: stat,wall + # connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 从库数据源 # SLAVE: # url: jdbc:mysql://127.0.0.1/ruoyi?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 @@ -44,16 +46,26 @@ spring: testWhileIdle: true testOnBorrow: false testOnReturn: false + # 配置监控统计拦截的filters + filters: stat,wall + # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 + connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 + webStatFilter: enabled: true + url-pattern: /* + exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" + sessionStatEnable: true + statViewServlet: enabled: true - # 设置白名单,不填则允许所有访问 - allow: url-pattern: /druid/* - # 控制台管理用户名和密码 + allow: 127.0.0.1 + deny: "" + reset-enable: false login-username: ruoyi login-password: 123456 + filter: stat: enabled: true @@ -62,10 +74,14 @@ spring: slow-sql-millis: 1000 merge-sql: true wall: + enabled: true config: multi-statement-allow: true + select-allow: true + stat-view-servlet: + enabled: true # 是否开启分布式事务,如不开启,请删除atomikos插件,否则atomikos相关驱动虽不生效但仍会启动 atomikos: - enabled: true \ No newline at end of file + enabled: false \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java index 3a94806..e1c0ede 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java @@ -125,7 +125,7 @@ public class DataScopeAspect { sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId())); } else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) { sqlString.append(StringUtils.format( - " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", + " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or array_position(string_to_array(ancestors , ','), CAST( {} AS TEXT)) IS NOT NULL )", deptAlias, user.getDeptId(), user.getDeptId())); } else if (DATA_SCOPE_SELF.equals(dataScope)) { if (StringUtils.isNotBlank(userAlias)) { diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java index c498928..738394b 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java @@ -9,11 +9,14 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties; +import com.alibaba.druid.support.jakarta.StatViewServlet; +import com.alibaba.druid.support.jakarta.WebStatFilter; import com.alibaba.druid.util.Utils; import jakarta.annotation.PreDestroy; @@ -81,6 +84,29 @@ public class DruidConfig { return registrationBean; } + @Bean + @ConditionalOnProperty(name = "spring.datasource.druid.webStatFilter.enabled", havingValue = "true") + public FilterRegistrationBean webStatFilter() { + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter()); + filterRegistrationBean.addUrlPatterns("/*"); + filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); + filterRegistrationBean.addInitParameter("sessionStatEnable", "true"); + return filterRegistrationBean; + } + + @Bean + @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") + public ServletRegistrationBean statViewServlet(DruidStatProperties properties) { + DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); + ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); + servletRegistrationBean.addInitParameter("loginUsername", config.getLoginUsername()); + servletRegistrationBean.addInitParameter("loginPassword", config.getLoginPassword()); + servletRegistrationBean.addInitParameter("allow", config.getAllow()); + servletRegistrationBean.addInitParameter("deny", config.getDeny()); + servletRegistrationBean.addInitParameter("resetEnable", String.valueOf(config.getResetEnable())); + return servletRegistrationBean; + } + public List getDruidDataSources() { return druidDataSources; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DynamicDataSourceProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DynamicDataSourceProperties.java index b7aa825..4d7edb9 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DynamicDataSourceProperties.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DynamicDataSourceProperties.java @@ -1,5 +1,6 @@ package com.ruoyi.framework.config; +import java.util.ArrayList; import java.util.Map; import java.util.Properties; @@ -18,6 +19,8 @@ public class DynamicDataSourceProperties { private Map datasource; private String primary; + + public Properties build(DataSourceProperties dataSourceProperties) { Properties prop = new Properties(); DruidProperties druidProperties = SpringUtils.getBean(DruidProperties.class); @@ -28,13 +31,18 @@ public class DynamicDataSourceProperties { prop.setProperty("minIdle", String.valueOf(druidProperties.getMinIdle())); prop.setProperty("maxActive", String.valueOf(druidProperties.getMaxActive())); prop.setProperty("maxWait", String.valueOf(druidProperties.getMaxWait())); - prop.setProperty("timeBetweenEvictionRunsMillis", String.valueOf(druidProperties.getTimeBetweenEvictionRunsMillis())); + prop.setProperty("timeBetweenEvictionRunsMillis", + String.valueOf(druidProperties.getTimeBetweenEvictionRunsMillis())); prop.setProperty("minEvictableIdleTimeMillis", String.valueOf(druidProperties.getMinEvictableIdleTimeMillis())); prop.setProperty("maxEvictableIdleTimeMillis", String.valueOf(druidProperties.getMaxEvictableIdleTimeMillis())); prop.setProperty("validationQuery", druidProperties.getValidationQuery()); prop.setProperty("testWhileIdle", String.valueOf(druidProperties.isTestWhileIdle())); prop.setProperty("testOnBorrow", String.valueOf(druidProperties.isTestOnBorrow())); prop.setProperty("testOnReturn", String.valueOf(druidProperties.isTestOnReturn())); + // 添加过滤器配置 + prop.setProperty("filters", "stat,wall"); + prop.setProperty("connectionProperties", "druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000"); + prop.setProperty("proxyFilters", ""); // 确保不会覆盖默认的过滤器 return prop; } @@ -76,6 +84,30 @@ public class DynamicDataSourceProperties { if (prop.getProperty("testOnReturn") != null) { dataSource.setTestOnReturn(Boolean.parseBoolean(prop.getProperty("testOnReturn"))); } + // 添加监控配置 + if (prop.getProperty("filters") != null) { + try { + dataSource.setFilters(prop.getProperty("filters")); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (prop.getProperty("connectionProperties") != null) { + dataSource.setConnectionProperties(prop.getProperty("connectionProperties")); + } + // 确保过滤器配置生效 + try { + if (prop.getProperty("filters") != null) { + dataSource.setFilters(prop.getProperty("filters")); + } + if (prop.getProperty("connectionProperties") != null) { + dataSource.setConnectionProperties(prop.getProperty("connectionProperties")); + } + // 启用防火墙功能 + dataSource.setProxyFilters(new ArrayList<>()); + } catch (Exception e) { + throw new RuntimeException("配置Druid过滤器失败", e); + } } public Map getDatasource() { diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DataSourceCreate.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DataSourceCreate.java index f09213d..03d6c4f 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DataSourceCreate.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DataSourceCreate.java @@ -7,7 +7,8 @@ import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.alibaba.druid.pool.xa.DruidXADataSource; +import com.alibaba.druid.pool.DruidDataSource; +// import com.alibaba.druid.pool.xa.DruidXADataSource; import com.ruoyi.common.service.datasource.CreateDataSource; import com.ruoyi.framework.config.DruidConfig; import com.ruoyi.framework.config.DynamicDataSourceProperties; @@ -22,10 +23,21 @@ public class DataSourceCreate implements CreateDataSource { private DruidConfig druidConfig; public DataSource createDataSource(String name, Properties prop) { - DruidXADataSource dataSource = new DruidXADataSource(); + DruidDataSource dataSource = new DruidDataSource(); druidConfig.getDruidDataSources().add(dataSource); + + // 设置基础属性 dataSource.setConnectProperties(prop); properties.setProperties(dataSource, prop); + + // 确保监控和防火墙功能开启 + try { + dataSource.setFilters("stat,wall"); + dataSource.init(); + } catch (Exception e) { + throw new RuntimeException("初始化数据源失败", e); + } + return dataSource; } } diff --git a/ruoyi-plugins/ruoyi-plugins-starter/pom.xml b/ruoyi-plugins/ruoyi-plugins-starter/pom.xml index 20048f9..cc31ea8 100644 --- a/ruoyi-plugins/ruoyi-plugins-starter/pom.xml +++ b/ruoyi-plugins/ruoyi-plugins-starter/pom.xml @@ -63,10 +63,10 @@ - +