文章思路
学一个东西我们首先要弄清楚它的使用场景,不然毫无意义。下面首先介绍 mybatis 插件的使用场景,然后再介绍如何使用,最后是它的原理。
使用场景
- 首先是网上都在说的分页插件,这个已经有人实现了,可以使用 PageHelper 插件,我们可以学习它怎么做的,但没必要重复造轮子,直接用就可以了
- 使用 mybatis 的时候发现如果是 PrepareStatement 的时候,sql 语句和参数是分开的,查找问题时非常不方便,这时候可以自定义插件把整合后的 sql 打印在控制台上。当然生产上需要关闭这个功能,因为不可能把大量的 sql 打印在日志文件中。
- 统计慢查询,可以用 mybatis 插件,设置一个慢查询阈值,把慢的 select 查询发送到消息中间件或存储在 mongodb 等,然后在页面做一个慢查询可视化来监控慢查询。
- 数据权限,这个我在项目中用过,可以使用 jsqlParser 来增加 sql 根据当前登录用户来追加查询条件,而不用硬编码在 sql 语句中。
如何使用
实现 org.apache.ibatis.plugin.Interceptor
接口,并指明要拦截 Mybatis 哪个类的哪个方法,然后把其注册到 mybatis 插件中就可以了。
Mybatis 拦截器只能拦截 Executor、ParameterHandler、StatementHandler、ResultSetHandler 四个对象里面的方法。
可拦截对象 | 解释 |
---|---|
Executor | MyBatis 执行器,是 MyBatis 调度的核心,负责 SQL 语句的生成和查询缓存的维护 |
ParameterHandler | 负责对用户传递的参数转换成 JDBC Statement 所需要的参数 |
StatementHandler | 封装了 JDBC Statement 操作,负责对 JDBC statement 的操作,如设置参数、将 Statement 结果集转换成 List 集合 |
ResultSetHandler | 负责将 JDBC 返回的 ResultSet 结果集对象转换成 List 类型的集合; |
快速使用,打印查询方法执行时间
- 定义拦截器
- 注册到 plugins 中,可以注册多个
@Intercepts(
// 拦截 Executor.query 方法,不是查缓存那个
@Signature(type = Executor.class,method = "query",args = {MappedStatement.class,Object.class, RowBounds.class, ResultHandler.class})
)
@Slf4j
public class TimeSpendInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {StopWatch stopWatch = new StopWatch();stopWatch.start();
// Invocation 的参数是看拦截的方法来的,这里 query 方法第一个参数是语句对象
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
String id = mappedStatement.getId();
Object proceed = null;
try {proceed = invocation.proceed();
}finally {stopWatch.stop();
log.info("sqlId:"+id+"执行时间为:"+stopWatch.getTime()+"ms");
}
return proceed;
}
@Override
public Object plugin(Object target) {return Plugin.wrap(target,this);
}
}
@Configuration
public class MybatisConfig {@Bean("timeSpendInterceptor")
public Interceptor interceptor2(){return new TimeSpendInterceptor();
}
}
最后成果:
[sqlId:com.sanri.test.testmybatis.mapper.BatchMapper.selectAll 执行时间为:548 ms]
完整项目地址
https://gitee.com/sanri/example/tree/master/test-mybatis
一些小推广
Excel 通用导入导出,支持 Excel 公式
https://blog.csdn.net/sanri1993/article/details/100601578
使用模板代码,从数据库生成代码,及一些项目中经常可以用到的小工具
https://blog.csdn.net/sanri1993/article/details/98664034