在 Java 微服务架构中,Druid 几乎成了 Spring Boot 项目的“标配”。
它不仅是高性能数据库连接池,更是集 SQL 监控、慢查询分析、SQL 防火墙、Web 请求追踪 于一体的全能型组件。
但现实是:90% 的项目只是“能跑”,却没真正“用好”。
你可能遇到过:
- /druid 页面 404 打不开;
- 监控面板里 SQL 列表空空如也;
- 慢查询不标红,危险操作不拦截;
- 甚至上线后才发现监控页面没设密码……
本文将带你系统性掌握 Druid 的正确使用姿势,并通过 Spring Boot 3 + MyBatis-Plus 实战演示,确保你的 Druid 不仅跑起来,更要跑得明白、跑得安全。
一、Druid 能做什么?为什么值得用?
Druid 不是简单的连接池替代品,它的核心能力包括:
| 连接池管理 | 高性能、防泄漏、自动回收 |
| SQL 监控 | 记录每条 SQL 的执行次数、耗时、事务状态 |
| 慢 SQL 检测 | 自动高亮超过阈值的慢查询 |
| SQL 防火墙(WallFilter) | 拦截 DROP、GRANT、注入等危险操作 |
| Web 请求关联 | 将 SQL 与 HTTP URI 关联,定位性能瓶颈 |
关键认知:Druid 的价值不在“连接池”,而在“可观测性 + 安全防护”。
二、正确集成步骤(Spring Boot 3 + MyBatis-Plus)
1. 依赖配置(版本是关键!)
<dependencies>
<!– Druid –>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.27</version>
</dependency>
</dependencies>
📌 避坑点 #1:Spring Boot 3 必须用 Druid ≥ 1.2.16,并且必须使用 druid-spring-boot-3-starter。
原因:SB3 基于 Jakarta EE 9,Servlet 包名从 javax.* 变为 jakarta.*。
旧版 Druid 无法注册 StatViewServlet,导致 /druid 404。
2. 核心配置(application.yml)
spring:
datasource:
url: jdbc:mysql://localhost:3306/test_druid
username: root
password: 111111
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 连接池基础参数
initial-size: 3
min-idle: 3
max-active: 10
max-wait: 10000
validation-query: SELECT 1
test-while-idle: true
# 启用监控 Servlet
stat-view-servlet:
enabled: true # ← 默认 false,必须显式开启
url-pattern: /druid/*
reset-enable: false # 禁止重置监控数据
login-username: monitor
login-password: S3cureP@ss!2026
# Web 请求统计
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: "*.js,*.css,/druid/*"
filter:
# 开启 StatFilter
stat:
enabled: true
db-type: mysql
slow-sql-millis: 2000
log-slow-sql: true
# 启用 SQL 防火墙
wall:
enabled: true
db-type: mysql
config:
drop-table-allow: false
truncate-allow: false
none-base-statement-allow: false # 拒绝非 CRUD 语句
# 慢 SQL 阈值(单位:毫秒)
connection-properties: druid.stat.slowSqlMillis=1000
关键配置说明:
- stat-view-servlet.enabled: true:开启监控页面
- wall.enabled: true:启用 SQL 防火墙
- stat.enabled: true :开启 StatFilter
- connection-properties:设置慢 SQL 判定阈值
3. 实体与 Mapper
// User.java
@Data
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
}
// UserMapper.java
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 用于防火墙测试的危险语句(语法合法!)
@Select("DROP TABLE IF EXISTS test_hack_table")
void executeDangerDDL();
@Select("GRANT USAGE ON *.* TO 'fake_user'@'localhost'")
void executeDangerDCL();
}
4. 测试 Controller(验证三大核心能力)
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
private UserMapper userMapper;
// ✅ INSERT
@PostMapping
public String createUser(@RequestBody UserDO user) {
userMapper.insert(user);
return "User created with ID: " + user.getId();
}
// ✅ SELECT
@GetMapping
public List<UserDO> listUsers() {
return userMapper.selectList(null);
}
// ✅ UPDATE
@PutMapping("/{id}")
public String updateUser(@PathVariable Long id, @RequestParam String newName) {
UpdateWrapper<UserDO> wrapper = new UpdateWrapper<>();
wrapper.eq("id", id).set("name", newName);
userMapper.update(null, wrapper);
return "User updated";
}
// ✅ DELETE
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
userMapper.deleteById(id);
return "User deleted";
}
// ✅ 真·慢 SQL(MySQL)
@GetMapping("/slow")
public Object realSlowSql() {
return userMapper.selectList(
new QueryWrapper<UserDO>().apply("SLEEP(3) = 0")
);
}
// ✅ 危险 DDL(会被 WallFilter 拦截)
@GetMapping("/danger/ddl")
public String testDDL() {
try {
userMapper.executeDangerDDL();
} catch (Exception e) {
return "WallFilter 拦截成功!原因: " + e.getMessage();
}
return "防火墙未生效!危险!";
}
// ✅ 高危 DCL
@GetMapping("/danger/dcl")
public String testDCL() {
try {
userMapper.executeDangerDCL();
} catch (Exception e) {
return "DCL 被拦截: " + e.getMessage();
}
return "DCL 未拦截!";
}
}
📌 避坑点 #2:SQL 监控/防火墙/慢查询不生效的常见原因
| SQL 不显示 | 未开启 StatFilter 或 MyBatis 未走 JDBC | 确保使用 JdbcTemplate 或 MyBatis-Plus(它们基于 JDBC) |
| 慢查询不标红 | 用 Thread.sleep() 代替真实慢 SQL | 使用 SLEEP(n) 或无索引大表查询 |
| 防火墙不拦截 | 测试语句语法非法(如 .apply("SHUTDOWN")) | 使用合法但危险的 DDL/DCL,如 DROP TABLE |
| 监控页面空白 | 未触发任何数据库操作 | 先调用 CRUD 接口,再刷新页面 |
三、验证效果:Druid 监控面板实测
启动应用后:
然后访问 http://localhost:8080/druid(输入账号密码),你会看到:
SQL 监控 Tab:
- INSERT INTO user … → 执行 1 次,耗时 ~5ms
- SELECT … WHERE SLEEP(3)=0 → 耗时 ~3000ms → 红色高亮!

防火墙效果:
- 控制台输出:com.alibaba.druid.wall.WallDenyException: deny sql : DROP TABLE …
- 监控页面可能显示“拒绝次数 +1”(取决于版本)

💡 真正的可观测性:每一条 SQL 都有迹可循,每一个风险都可被拦截。
四、安全加固:别让 Druid 成为后门
即使配了密码,仍需纵深防御:
1. 禁止重置监控数据
reset-enable: false # 防止攻击者清空日志掩盖痕迹
2. 限制访问 IP(Spring Security)
.requestMatchers("/druid/**").hasIpAddress("10.0.0.0/8")
3. 密码不硬编码
login-password: ${DRUID_MONITOR_PASSWORD}
🔒 安全原则:监控页面 = 管理后台,必须按最高权限保护。
五、总结:Druid 正确使用姿势 Checklist
版本匹配:Spring Boot 3 → Druid ≥ 1.2.16,druid-spring-boot-3-starter
显式开启:stat-view-servlet.enabled: true
真实测试:用 SLEEP() 测慢 SQL,用 DROP 测防火墙
安全加固:强密码 + IP 限制 + 禁重置
持续观察:定期查看监控面板,优化高频/慢 SQL
结语
Druid 的强大,不在于“默认就能用”,而在于你是否真正理解并激活了它的全部能力。
当你能在监控页面清晰看到:
- 每一条业务 SQL 的执行轨迹,
- 每一个慢查询的性能瓶颈,
- 每一次危险操作的拦截记录,
你才真正拥有了一个可观测、可防御、可优化的数据访问层。
📌 完整可运行示例代码:
https://github.com/iweidujiang/java-tricks-lab/tree/main/springboot-druid-safe-demo
欢迎点赞、收藏、转发!


