导读:本期聚焦于刘卫东创作的《SpringBoot项目如何整合Druid数据库连接池?常见错误怎么解决?》,敬请观看详情。整合Druid最常见的问题不是依赖冲突,而是监控配置遗漏和连接参数不匹配。很多项目把starter加上、数据源切换成Druid后发现SQL日志不打印,监控页一直404,或者在启动阶段就提示驱动加载失败。这类现象通常和三个环节有关:依赖版本与Spring Boot是否匹配、StatViewServlet与WebStatFilter有没有真正生效、连接池的校验SQL与时区参数是否正确。本文会先给出最小可用的依赖与配置,再说明监控页面和慢SQL统计的开启方式,然后集中排查启动报错、监控页打不开、wall过滤器误拦截以及多数据源下监控失效等高频错误。按文中清单逐项检查,不需要反复重启试错,基本可以一次把Druid连接池与监控功能跑通。

Spring Boot 2.x 项目在没有手动指定数据源时,默认使用 HikariCP。HikariCP 的优点是启动快、占用资源少,但它不提供图形化 SQL 监控和慢查询面板,排查线上 SQL 问题时通常要借助日志或 APM 工具。Druid 则把连接池、SQL 统计、防火墙和监控页面做成了一个整体,尤其适合业务开发阶段快速观察 SQL 执行次数、响应时间和慢查询分布。整合 Druid 的步骤可以拆成三块:切换数据源、补齐连接池参数、开启监控功能。真正容易出错的并不是核心配置本身,而是监控页面没有生效、驱动类名写错、wall 过滤器误拦截或者多数据源下手动构建 DataSource 时漏掉 filters。下面按完整流程和错误分类展开。

SpringBoot项目如何整合Druid数据库连接池?常见错误怎么解决?

一、引入依赖并完成基础配置

使用官方提供的 druid-spring-boot-starter 是最省事的整合方式,它内部已经包含了 DruidDataSource 自动配置、StatFilter、WallFilter 以及监控 Servlet 的注册能力。需要先确认 Spring Boot 版本,Boot 2.x 可以使用较新的 1.2.x 版本,Boot 3.x 需要选择支持 jakarta.servlet 的 Druid 版本,建议使用 1.2.20 以上。依赖只需要一个,不必再单独引入 druid,否则可能出现重复的 druid 类冲突。

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.23</version>
</dependency>

依赖加入后,如果项目里同时存在 HikariCP 的自动配置,通常可以通过 spring.datasource.type 显式指定为 DruidDataSource,避免加载顺序带来的不确定结果。基础连接信息和连接池参数可以放在 application.yml 或 application.properties 中。下面用 properties 格式给出一个最小可运行配置,MySQL 8 需要特别注意驱动类名和 URL 参数。

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo_db?serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=123456

# 连接池初始化参数
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-active=20
spring.datasource.druid.max-wait=60000
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.min-evictable-idle-time-millis=300000
spring.datasource.druid.validation-query=SELECT 1
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false

这段配置中,spring.datasource.type 的作用是告诉 Spring Boot 使用 Druid 作为 DataSource 实现,spring.datasource.druid 前缀下的参数由 Druid starter 进行绑定。initial-size、min-idle、max-active 控制连接池初始化数量和容量,validation-query 用来检测连接活性。test-while-idle=true 配合 time-between-eviction-runs-millis 可以在空闲回收线程中及时剔除失效连接,避免真正执行 SQL 时才发现连接已经断开。

二、开启监控页面与 SQL 统计

Druid 的监控页面由 StatViewServlet 提供,Web 请求统计由 WebStatFilter 提供。使用 starter 时不需要自己写 Servlet 注册代码,只需要打开对应配置项。StatViewServlet 默认关闭,所以很多人没有配置 enabled=true 就去访问 /druid 页面,结果必然是 404。

# 监控页 Servlet
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin123
spring.datasource.druid.stat-view-servlet.allow=127.0.0.1
spring.datasource.druid.stat-view-servlet.deny=192.168.1.10

# Web 统计过滤器
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*

# SQL 统计
spring.datasource.druid.filter.stat.enabled=true
spring.datasource.druid.filter.stat.slow-sql-millis=2000
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.merge-sql=true

上面的配置中,stat-view-servlet.url-pattern 设置了监控页地址前缀,启动后访问 http://localhost:8080/druid/index.html 可以看到登录页。allow 表示白名单,deny 表示黑名单,两者都支持 IP 或 IP 段。即使在内网环境也不建议把 allow 留空后再关闭登录,否则只要知道端口和路径的人就能看到完整的 SQL 记录。

SQL 统计部分由 filter.stat 控制。slow-sql-millis 定义慢查询阈值,单位是毫秒;log-slow-sql 控制是否在日志中输出慢 SQL;merge-sql 可以把参数化后的 SQL 与真实参数合并展示。比如一条 SELECT * FROM user WHERE id = ? 在监控页中既能看模板,也能看到实际执行时 id 具体是多少,对开发调试非常有帮助。

如果不想依赖 starter 的监听器自动注册逻辑,也可以自己写一个配置类,用 ServletRegistrationBean 和 FilterRegistrationBean 注册 StatViewServlet 与 WebStatFilter。这种方式更灵活,适合需要动态读取账号密码或按环境控制是否开启监控的项目。

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
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;

@Configuration
public class DruidMonitorConfig {

    @Bean
    public ServletRegistrationBean<StatViewServlet> statViewServlet() {
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
        bean.addInitParameter("loginUsername", "admin");
        bean.addInitParameter("loginPassword", "admin123");
        bean.addInitParameter("allow", "127.0.0.1");
        return bean;
    }

    @Bean
    public FilterRegistrationBean<WebStatFilter> webStatFilter() {
        FilterRegistrationBean<WebStatFilter> bean = new FilterRegistrationBean<>(new WebStatFilter());
        bean.addUrlPatterns("/*");
        bean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return bean;
    }
}

手动注册时要注意,loginUsername 和 loginPassword 是 StatViewServlet 的初始化参数名,不能写错。exclusions 参数里多个静态资源后缀用英文逗号分隔,这行配置如果漏掉 /druid/*,监控页面自身的请求也可能被 WebStatFilter 统计干扰。

三、监控页打不开或返回 404 的排查

监控页打不开和 SQL 监控无数据要分开判断。404 一般说明 StatViewServlet 没有注册成功,或者访问路径不对;登录页能打开但 SQL 统计为空,则说明 filters 没有生效,或者数据源没有经过 StatFilter。

先检查 pom.xml 是否真的引入了 druid-spring-boot-starter,而不是只引入了 druid 基础包。只引入 druid 基础包不会自动注册监控 Servlet。然后看配置项 stat-view-servlet.enabled 是否为 true,url-pattern 是否写成 /druid/*,访问时是否携带了项目上下文路径。例如设置了 server.servlet.context-path=/api,那么监控地址就是 http://localhost:8080/api/druid/index.html,而不是直接访问 /druid。

如果项目集成了 Spring Security 或 Shiro,需要把监控路径放行。Spring Security 下通常可以写一个配置类,允许匿名访问 /druid/**,否则登录请求会被安全过滤器拦下来,表现就是一直跳转登录页或返回 403。

http.authorizeHttpRequests()
    .requestMatchers("/druid/**").permitAll()
    .anyRequest().authenticated();

还有一种情况是自定义了静态资源映射,导致 /druid 被静态资源处理器抢先返回 404。此时可以检查 WebMvcConfigurer 的 addResourceHandlers 是否覆盖了默认处理,必要时对监控路径单独做排除。总之 404 问题优先按依赖、配置、上下文路径、安全框架、静态资源映射这个顺序排查,基本能快速定位。

四、启动报错与 SQL 执行失败

启动阶段最常见的错误是驱动类找不到或驱动类名过时。MySQL 5.x 时代的 com.mysql.jdbc.Driver 在 MySQL 8 驱动中虽然仍保留,但会输出提醒,部分新版本驱动直接移除。Spring Boot 2.x 和 3.x 项目建议统一使用 com.mysql.cj.jdbc.Driver。另一个报错是 Public Key Retrieval is not allowed,这是因为 MySQL 8 默认使用 caching_sha2_password 认证,JDBC URL 中需要加上 allowPublicKeyRetrieval=true。

spring.datasource.url=jdbc:mysql://localhost:3306/demo_db?serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

如果数据库连接本身没有问题,但启动初始化连接池时一直报 testWhileIdle 的校验失败,优先检查 validation-query 是否适配当前数据库。MySQL 下通常用 SELECT 1,Oracle 下则需要 SELECT 1 FROM DUAL。还要确认 URL 中 serverTimezone 参数是否带上,否则可能出现时区识别异常。

运行期 SQL 执行失败里,比较隐蔽的是 Druid 的 wall 防火墙拦截。典型日志会包含 sql injection violation。比如业务里有 update 关联表、delete 关联表或 insert ... select 语句,这些语句在默认 wall 规则中可能命中黑名单。如果确认不是注入风险,可以关闭 wall 过滤器,或者调整具体拦截项。

spring.datasource.druid.filter.wall.enabled=false

关闭 wall 会失去防注入能力,不建议直接在生产环境关闭。如果只是单条 SQL 必须执行,更推荐使用白名单语法配置。Druid wall 的 config 参数较多,遇到误拦截时可以先把日志中的拦截规则打印出来,再针对性放行。多语句场景下才需要开启 multi-statement-allow,普通 CRUD 不需要打开这个选项,否则会扩大 SQL 注入面。

五、多数据源场景下监控失效

当项目需要同时连接主库和从库、或连接两个不同业务库时,往往不能再用 starter 的自动配置,而是通过 @Configuration 手动创建多个 DataSource。手动创建时容易漏掉两个关键点:一是没有给每个 DruidDataSource 设置 filters=stat,wall,二是没有用 @Primary 标明主数据源,导致 MyBatis 或 JPA 自动装配时找不到唯一候选。

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    @Bean(name = "primaryDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.druid.primary")
    public DataSource primaryDataSource() {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        dataSource.setFilters("stat,wall");
        return dataSource;
    }

    @Bean(name = "secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.secondary")
    public DataSource secondaryDataSource() {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        dataSource.setFilters("stat,wall");
        return dataSource;
    }
}

上面代码用 @ConfigurationProperties 分别绑定 primary 和 secondary 两个前缀,这样配置文件仍然可以保持清晰。每个数据源都调用 setFilters("stat,wall"),SQL 监控才会采集完整。只给其中一个数据源设置 filters,监控页里只能看到该数据源的执行记录,另一个数据源始终空白,这种现象很容易被误认为监控功能没生效。

多数据源还需要关注事务和 Mapper 扫描范围。@Primary 决定默认注入的数据源,@MapperScan 的 sqlSessionFactoryRef 也要与对应数据源匹配,否则 mapper 会去错误的数据源里找表。事务管理器需要分别创建,并在 @Transactional 注解中指定 transactionManager,不要只使用默认事务管理器。

spring.datasource.druid.primary.url=jdbc:mysql://localhost:3306/primary_db?useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.druid.primary.username=root
spring.datasource.druid.primary.password=123456
spring.datasource.druid.primary.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.druid.secondary.url=jdbc:mysql://localhost:3306/secondary_db?useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.druid.secondary.username=root
spring.datasource.druid.secondary.password=123456
spring.datasource.druid.secondary.driver-class-name=com.mysql.cj.jdbc.Driver

配置文件可以这样组织:主库和从库的前缀分别为 spring.datasource.druid.primary 和 spring.datasource.druid.secondary,连接池参数可以复用,但 URL 和账号通常不同。需要特别注意的是,手动创建数据源后,starter 自动配置不会自动读取 spring.datasource.druid 下的通用参数,必须在 @ConfigurationProperties 中绑定自己的前缀,否则连接池容量、校验参数都会丢失。

六、连接池参数调优建议

Druid 连接池是否稳定,很大程度上取决于 initial-size、min-idle、max-active 和 max-wait 这几个参数。initial-size 和 min-idle 可以保持一致,避免启动后还要频繁创建连接。max-active 要根据数据库实际能承受的连接数来设,不是越大越好。应用实例很多时,总连接数等于实例数乘以 max-active,如果超过数据库 max_connections,就会出现拒绝连接或连接超时。

max-wait 控制获取连接时的最大等待时间,生产环境建议设置为 5000 到 10000 毫秒,超时后快速失败,避免请求线程长时间阻塞。validation-query 在 MySQL 下使用 SELECT 1 就足够,test-on-borrow 不建议打开,因为每次借连接都执行一次校验会明显增加数据库开销。空闲检测通过 test-while-idle 配合 time-between-eviction-runs-millis 更合适。

对于使用预编译语句较多的系统,建议开启 pool-prepared-statements 并把 max-pool-prepared-statement-per-connection-size 设置为 20 左右。这个参数控制单个连接中 PreparedStatement 对象缓存数量,过大会占用较多内存,过小则起不到复用效果。慢 SQL 阈值在开发环境可以设置成 1000 毫秒,生产环境先设置 2000 到 3000 毫秒,再根据实际监控数据逐步收紧。

spring.datasource.druid.max-active=30
spring.datasource.druid.max-wait=10000
spring.datasource.druid.pool-prepared-statements=true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20

按照这套配置思路,Druid 连接池可以提供稳定的连接管理和足够的监控信息。遇到问题时不要只盯着报错堆栈,先确认连接池配置是否正确加载、监控 Servlet 是否注册、filters 是否对目标数据源生效,这三处检查完,大多数整合问题都能定位。

Spring BootDruid连接池数据库连接池修改时间:2026-09-25 08:53:33

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0925/61642.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。