欢迎光临
我们一直在努力

Druid 正确使用姿势全解析:Spring Boot 3 + MyBatis-Plus 集成实战指南

在 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 监控面板实测

启动应用后:

  • 调用 POST /api/user → 新增数据
  • 调用 GET /api/user/slow → 触发慢 SQL
  • 调用 GET /api/user/danger/ddl → 触发防火墙拦截
  • 然后访问 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

    欢迎点赞、收藏、转发!

    赞(0)
    未经允许不得转载:171主机测评 » Druid 正确使用姿势全解析:Spring Boot 3 + MyBatis-Plus 集成实战指南
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址