摘要
本文介绍了MyBatis拦截器的作用机制、注意事项、拦截顺序以及四类拦截点的应用场景和用法。
认识MyBatis拦截器
MyBatis拦截器是MyBatis提供的一种扩展机制,基于Java动态代理和反射机制实现,允许开发者在SQL执行过程中的关键节点插入自定义逻辑。
生命周期
Interceptor接口的三个方法。intercept实现所有拦截逻辑,plugin通过Plugin.wrap(target,this)为目标对象创建代理,setProperties用于读取配置中的属性值。

步骤实现
1.拦截器注册:通过@Intercepts注解指定拦截点。
2.代理对象生成:MyBatis使用Plugin类为目标对象(如Executor)创建代理。
3.方法拦截:当调用目标方法时,代理会触发拦截器的intercept方法。
4.逻辑执行:在intercept中可修改参数、执行原方法、处理返回值。
拦截顺序
StatementHandler.prepare
→ParameterHandler.setParameters
→Executor.update/query
→ResultSetHandler.handleResultSets
注意事项
- 性能影响:拦截器会增加SQL执行的额外开销,避免在高频操作中使用复杂逻辑。
- 线程安全:使用ThreadLocal存储搜索参数,确保线程隔离。
- 参数绑定:动态生成的参数需要与ParameterMapping对应,避免参数丢失。
- SQL注入:参数使用?占位符绑定,确保安全。
- 避免过度拦截:不同的拦截点可能会重复拦截同一个 SQL 操作,需注意逻辑冲突。
可选拦截点应用场景
- 数据脱敏:ResultSetHandler拦截,在结果集中对敏感字段如手机号、身份证号进行脱敏处理。
- 自动分页:StatementHandler拦截,自动拼接分页SQL。
- 参数预处理:ParameterHandler拦截,对入参进行加密、格式校验或默认值填充。
- 日志监控:Executor拦截,统计SQL执行时间,识别慢查询。
四大类
在MyBatis中,使用@Intercepts注解定义拦截器时,需要通过@Signature指定拦截的目标接口、方法和参数,分为四大类:
StatementHandler部分
less
//用于拦截 SQL 语句的准备阶段
@Intercepts({
@Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class })
})
public class PrepareInterceptor implements Interceptor { // 实现 intercept 方法 }
//用于拦截参数绑定阶段
@Intercepts({
@Signature(type = StatementHandler.class, method = "parameterize", args = { Statement.class })
})
public class ParameterizeInterceptor implements Interceptor { // 实现 intercept 方法 }
//用于拦截 INSERT、UPDATE、DELETE 的执行阶段
@Intercepts({
@Signature(type = StatementHandler.class, method = "update", args = { Statement.class })
})
public class UpdateStatementInterceptor implements Interceptor { // 实现 intercept 方法 }
//用于拦截 SELECT 查询的执行阶段。
@Intercepts({
@Signature(type = StatementHandler.class, method = "query", args = { Statement.class, ResultHandler.class })
})
public class QueryStatementInterceptor implements Interceptor { // 实现 intercept 方法 }
ParameterHandler部分
less
//用于拦截参数绑定到 PreparedStatement 的阶段
@Intercepts({
@Signature(type = ParameterHandler.class, method = "setParameters", args = { PreparedStatement.class })
})
public class ParameterInterceptor implements Interceptor { // 实现 intercept 方法 }
//用于拦截获取参数对象的阶段
@Intercepts({
@Signature(type = ParameterHandler.class, method = "getParameterObject", args = {})
})
public class GetParameterInterceptor implements Interceptor { // 实现 intercept 方法 }
Executor部分
less
//用于拦截 INSERT、UPDATE、DELETE 操作
@Intercepts({
@Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class UpdateInterceptor implements Interceptor { // 实现 intercept 方法 }
//用于拦截 SELECT 查询。
@Intercepts({
@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class })
})
public class QueryInterceptor implements Interceptor { // 实现 intercept 方法 }
//用于拦截事务提交操作
@Intercepts({
@Signature(type = Executor.class, method = "commit", args = { boolean.class })
})
public class CommitInterceptor implements Interceptor { // 实现 intercept 方法 }
//用于拦截事务回滚操作
@Intercepts({
@Signature(type = Executor.class, method = "rollback", args = { boolean.class })
})
public class RollbackInterceptor implements Interceptor { // 实现 intercept 方法 }
//同时拦截 Executor.update 和 StatementHandler.prepare
@Intercepts({
@Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }),
@Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class })
})
public class MyInterceptor implements Interceptor { // 实现 intercept 方法 }
ResultSetHandler部分
less
//用于拦截结果集的处理阶段
@Intercepts({
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = { Statement.class })
})
public class ResultHandlerInterceptor implements Interceptor { // 实现 intercept 方法 }
//用于拦截存储过程输出参数的处理阶段
@Intercepts({
@Signature(type = ResultSetHandler.class, method = "handleOutputParameters", args = { CallableStatement.class })
})
public class OutputParameterInterceptor implements Interceptor { // 实现 intercept 方法 }
总结
以上我们了解了MyBatis拦截器的作用机制、注意事项及拦截顺序,四类拦截点,当我们使用注解自定义拦截器时,需要遵循特定组合写法,并实现方法细节。
关注公众号:咖啡Beans
在这里,我们专注于软件技术的交流与成长,分享开发心得与笔记,涵盖编程、AI、资讯、面试等多个领域。无论是前沿科技的探索,还是实用技巧的总结,我们都致力于为大家呈现有价值的内容。期待与你共同进步,开启技术之旅。