Mybatis拦截器
核心部件
MyBatis 提供了一个插件机制,允许开发者通过拦截器(Interceptor)拦截 MyBatis 的执行流程,方便进行一些扩展功能的开发。MyBatis 可以通过拦截四类核心对象的方法,这四类对象分别是:
- Executor 拦截器:负责拦截 SQL 的执行流程,如查询和更新。
- ParameterHandler 拦截器:拦截参数设置的过程,用于处理 SQL 参数。
- ResultSetHandler 拦截器:拦截结果集处理,操作查询结果。
- StatementHandler 拦截器:拦截 SQL 语句的生成和执行。
Executor 拦截器
Executor
是 MyBatis 的执行器,它负责调用StatementHandler
操作数据库,并把结果集通过ResultSetHandler
进行自动映射,另外,它还处理二级缓存的操作。
拦截的常见方法有:
update(MappedStatement ms, Object parameter)
query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler)
commit(boolean required)
rollback(boolean required)
应用场景:
- 事务控制:拦截
commit
或rollback
进行自定义的事务处理。 - 缓存增强:自定义缓存逻辑,可以拦截
query
,进行缓存层面的增强。
示例:
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class ExecutorInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 自定义逻辑处理
return invocation.proceed();
}
}
ParameterHandler 拦截器
ParameterHandler
负责将用户传递的参数处理后,绑定到 SQL 语句中。在 SQL
执行前,MyBatis 会使用 ParameterHandler
处理参数,将其转换为 JDBC 的 PreparedStatement
需要的参数形式。
拦截的常见方法有:
setParameters(PreparedStatement ps)
应用场景:
- 参数审计:对传入的参数进行检查、修改或记录。
- 自动加密:对于需要传递敏感信息的字段,在这里可以进行加密处理。
示例:
@Intercepts({
@Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class})
})
public class ParameterHandlerInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 参数处理逻辑
return invocation.proceed();
}
}
ResultSetHandler 拦截器
ResultSetHandler
负责处理从数据库中查询的结果集,将其转换为 Java 对象。MyBatis 通过 ResultSetHandler
将 SQL 查询结果与映射的 Java 类进行匹配。
拦截的常见方法有:
handleResultSets(Statement stmt)
应用场景:
- 数据脱敏:查询出的敏感信息,可以在这里进行脱敏处理。
- 结果集缓存:通过拦截查询结果,可以将其缓存,以减少 重复的数据库访问。
示例:
@Intercepts({
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class ResultSetHandlerInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 结果集处理逻辑
return invocation.proceed();
}
}
StatementHandler 拦截器
StatementHandler
负责执行 SQL 语句。MyBatis 在执行 SQL 之前会生成 Statement
(如 PreparedStatement
或 CallableStatement
),并将 SQL 语句发送给数据库。拦截 StatementHandler
可以对 SQL 语句进行修改,或对 SQL 执行的行为进行控制。
拦截的常见方法有:
prepare(Connection connection, Integer transactionTimeout)
parameterize(Statement stmt)
batch(Statement stmt)
update(Statement stmt)
query(Statement stmt, ResultHandler resultHandler)
应用场景:
- SQL 日志打印:可以在 SQL 发送到数据库之前拦截 SQL,进行日志打印。
- SQL 优化:拦截
prepare
方法对生成的 SQL 语句进行修改,或进行某种优化(比如自动加上分页或排序)。
示例:
@Intercepts({
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class StatementHandlerInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// SQL 语句处理逻辑
return invocation.proceed();
}
}