最近有个需求,想对mybatis的sql查询的条件进行修改,网上查了一下,很多人说可以使用Interceptor,之前没有用过,所以做了些了解,做一下记录。
主要想了解一下基本的时序,写了点测试代码,如下:
/**
* 完成插件签名:
* 告诉MyBatis当前插件用来拦截哪个对象的哪个方法
* 四大对象(Executor,StatementHandler,ParameterHandler,ResultSetHandler)
* type 指四大对象拦截哪个对象,
* method : 代表拦截哪个方法 ,在StatementHandler 中查看,需要拦截的方法
* args :代表参数
*
*/
@Intercepts(
value = {
@org.apache.ibatis.plugin.Signature(
type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@org.apache.ibatis.plugin.Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class, Integer.class}),
@org.apache.ibatis.plugin.Signature(
type = ParameterHandler.class,
method = "setParameters",
args = {PreparedStatement.class}),
@org.apache.ibatis.plugin.Signature(
type = ResultSetHandler.class,
method = "handleResultSets",
args = {Statement.class})
}
)
public class SqlInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget();
Object result = null;
if (target instanceof Executor) {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
Object parameter = invocation.getArgs()[1];
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
String oldsql = boundSql.getSql();
//LogUtil.info("old:" + oldsql);
long start = System.currentTimeMillis();
Method method = invocation.getMethod();
/**执行方法*/
result = invocation.proceed();
long end = System.currentTimeMillis();
//LogUtil.info("[TimerInterceptor] execute [" + method.getName() + "] cost [" + (end - start) + "] ms");
LogUtil.info("xxxxxxx Executor Interceptor, method " + method.getName());
}else if(target instanceof StatementHandler){
Method method = invocation.getMethod();
/**执行方法*/
result = invocation.proceed();
LogUtil.info("xxxxxx StatementHandler Interceptor, method " + method.getName());
}else if(target instanceof ParameterHandler){
Method method = invocation.getMethod();
/**执行方法*/
result = invocation.proceed();
LogUtil.info("xxxxxx ParameterHandler Interceptor, method " + method.getName());
}else if(target instanceof ResultSetHandler){
Method method = invocation.getMethod();
/**执行方法*/
result = invocation.proceed();
LogUtil.info("xxxxxx ResultSetHandler Interceptor, method " + method.getName());
}
return result;
}
@Override
public Object plugin(Object target) {
Object wrap = Plugin.wrap(target, this);
return wrap;
}
@Override
public void setProperties(Properties properties) {
}
}
经过调试,画了一个时序图,可能有些地方不太准确,但时序应该是对的。如下: