MyBatis-Plus 提供了强大的功能扩展机制,其中 BlockAttackInnerInterceptor
是防止全表更新或删除操作的安全插件。在生产环境中,误操作如 UPDATE table SET column = value
或 DELETE FROM table
而不带 WHERE
条件,可能导致灾难性后果。
一、核心概念
1. 什么是 BlockAttackInnerInterceptor
?
BlockAttackInnerInterceptor
是 MyBatis-Plus 内置的 SQL 拦截器(Interceptor),用于拦截没有WHERE
条件的UPDATE
和DELETE
操作。- 当检测到全表更新或删除时,抛出异常,阻止执行,防止误操作导致数据丢失。
- 属于
InnerInterceptor
接口实现类,通过 MyBatis-Plus 的插件机制注入执行流程。
2. 适用场景
- 生产环境防止误删/误更。
- 开发、测试环境调试时可选择性关闭。
- 多人协作项目中统一安全策略。
二、操作步骤(非常详细)
步骤 1:引入 MyBatis-Plus 依赖
确保项目中已正确引入 MyBatis-Plus(以 Spring Boot 为例):
<!-- Maven -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version> <!-- 推荐使用最新稳定版 -->
</dependency>
步骤 2:创建 MyBatis Plus 配置类
创建一个配置类(如 MyBatisPlusConfig.java
),注册拦截器。
package com.example.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
/**
* 配置 MyBatis-Plus 插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加防止全表更新与删除的拦截器
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}
}
步骤 3:验证拦截器是否生效
编写一个测试用例,尝试执行无条件删除:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public void badDelete() {
// ❌ 危险操作:无 WHERE 条件的删除
userMapper.delete(null); // 或 new QueryWrapper<>()
}
}
执行时将抛出异常:
Caused by: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException:
Prohibition of full table deletion, must have where condition
✅ 表明插件已生效,成功阻止全表删除。
三、常见错误与解决方案
错误现象 | 原因 | 解决方案 |
---|---|---|
插件未生效,仍可全表删除 | 未正确注册 MybatisPlusInterceptor |
检查配置类是否被 Spring 扫描,@Configuration 是否遗漏 |
启动报错 ClassNotFoundException |
版本不兼容或依赖缺失 | 升级 MyBatis-Plus 至 3.4.0+,确认依赖完整 |
其他 SQL 报错或拦截异常 | 拦截器顺序冲突 | BlockAttackInnerInterceptor 通常无需调整顺序,若与其他插件共用,注意添加顺序 |
测试环境也需要放行 | 生产安全策略影响开发调试 | 使用条件注入或配置开关 |
四、注意事项
版本要求:
BlockAttackInnerInterceptor
自 MyBatis-Plus 3.4.0 版本引入。- 低于此版本请升级。
仅拦截 UPDATE/DELETE:
- 不影响
SELECT
操作。 INSERT
操作不受影响。
- 不影响
Wrapper 为空时触发拦截:
- 当传入
null
或空Wrapper
(如new QueryWrapper<>()
)时,视为无条件操作。
- 当传入
逻辑删除不受影响:
- 若使用
@TableLogic
,逻辑删除仍需条件,否则也会被拦截。
- 若使用
五、使用技巧
技巧 1:按环境启用/禁用插件
@Bean
@ConditionalOnProperty(name = "mybatis-plus.block-attack.enable", havingValue = "true", matchIfMissing = true)
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}
配置文件中控制:
# application-prod.yml
mybatis-plus:
block-attack:
enable: true
# application-dev.yml
mybatis-plus:
block-attack:
enable: false
⚠️ 建议生产环境强制开启,开发环境可关闭便于调试。
技巧 2:自定义提示信息(需扩展)
原生不支持自定义异常信息,但可通过继承或 AOP 捕获异常后包装:
@ExceptionHandler(MybatisPlusException.class)
public ResponseEntity<?> handleMybatisPlusException(MybatisPlusException e) {
if (e.getMessage().contains("Prohibition of full table deletion")) {
return ResponseEntity.badRequest().body("禁止执行无条件删除操作,请检查 WHERE 条件");
}
return ResponseEntity.status(500).body("数据库操作异常");
}
六、最佳实践
生产环境必须开启
所有生产部署必须启用BlockAttackInnerInterceptor
,作为数据安全第一道防线。结合代码审查与权限控制
插件是最后一道防线,开发阶段应通过代码规范、CR(Code Review)避免写出无条件操作。日志监控
拦截异常应记录日志,便于审计和排查误操作尝试。单元测试覆盖
编写测试用例验证插件行为,确保配置正确。
七、性能优化
BlockAttackInnerInterceptor
性能开销极低,仅在 SQL 构建时检查WHERE
条件是否存在。- 无额外数据库查询或复杂计算。
- 无需担心性能影响,建议始终开启。
八、总结
项目 | 内容 |
---|---|
插件名称 | BlockAttackInnerInterceptor |
作用 | 防止全表 UPDATE / DELETE |
注册方式 | 通过 MybatisPlusInterceptor.addInnerInterceptor() |
最低版本 | MyBatis-Plus 3.4.0 |
是否影响性能 | 几乎无影响 |
推荐使用场景 | 所有生产环境 |
✅ 一句话总结:
在 MyBatis-Plus 配置类中注册 BlockAttackInnerInterceptor
,即可轻松防止全表更新与删除,是保障数据安全的必备配置。