问题背景
在最近的项目开发中遇到一个需求 需要对mysql做一些慢查询、大结果集等异常指标进行收集监控,从运维角度并没有对mysql进行统一的指标搜集,所以需要通过代码层面对指标进行收集,我采用的方法是通过mybatis的Interceptor拦截器进行指标收集在开发中出现了自定义拦截器 对于查询无法进行拦截的问题几经周折后终于解决,故进行记录学习,分享给大家下次遇到少走一些弯路;
mybatis拦截器使用
像springmvc一样,mybatis也提供了拦截器实现,对Executor、StatementHandler、ResultSetHandler、ParameterHandler提供了拦截器功能。
使用方法:
在使用时我们只需要 implements org.apache.ibatis.plugin.Interceptor类实现 方法头标注相应注解即可 如下代码会对CRUD的操作进行拦截:
@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})
})
复制代码
注解参数介绍:
- @Intercepts:标识该类是一个拦截器;
- @Signature:指明自定义拦截器需要拦截哪一个类型,哪一个方法
拦截的类(type) | 拦截的方法(method) |
---|---|
Executor | update, query, flushStatements, commit, rollback,getTransaction, close, isClosed |
ParameterHandler | getParameterObject, setParameters |
StatementHandler | prepare, parameterize, batch, update, query |
ResultSetHandler | handleResultSets, handleOutputParameters |
- Executor:提供了增删改查的接口 拦截执行器的方法.
- StatementHandler:负责处理Mybatis与JDBC之间Statement的交互 拦截参数的处理.
- ResultSetHandler:负责处理Statement执行后产生的结果集,生成结果列表 拦截结果集的处理.
- ParameterHandler:是Mybatis实现Sql入参设置的对象 拦截Sql语法构建的处理。
官方代码示例:
@Intercepts({@Signature(type = Executor.class, method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class TestInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget(); //被代理对象
Method method = invocation.getMethod(); //代理方法
Object[] args = invocation.getArgs(); //方法参数
// do something ...... 方法拦截前执行代码块
Object result = invocation.proceed();
// do something .......方法拦截后执行代码块
return result;
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
}
复制代码
setProperties方法
因为mybatis框架本身就是一个可以独立使用的框架,没有像Spring这种做了很多的依赖注入。 如果我们的拦截器需要一些变量对象,而且这个对象是支持可配置的。 类似于Spring中的@Va