Interceptor
是MyBatis提供的一个插件(plugin扩展)。代表拦截器,可以拦截代码中的数据库访问操作,即Statement操作
拦截后,可以去修改正在执行的SQL语句,可以额外访问数据库,可以实现若干数据的计算和处理。
使用场景并不多,针对某类型的SQL实现拦截工具。粒度太粗糙,影响执行效率。
具体代码
自定义拦截器(需实现Interceptor接口,借助注解实现)
//声明拦截器
@Intercepts(value = {
/**
* 要拦截的具体类型
* method:query对应statement中的executeQuery(),update 对应statement中的executeUpdate()
* type:拦截的驱动的类型,Executor是MyBatis提供的底层访问数据库时的封装接口,类似于JDBC的Statement
* args:通知MyBatis框架,当前拦截器中拦截方法intercept参数invocation需要提供多少个参数
*/
@Signature(method = "query", type=Executor.class,args= {MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class})
}
)
public class PageInterceptor implements Interceptor{
@Override
public Object intercept(Invocation arg0) throws Throwable {
//获取需要的参数信息,提取顺序和注解声明顺序相关
Object[] param = arg0.getArgs();
//获取第一个参数MappedStatement
MappedStatement mStatement = (MappedStatement) param[0];
//获取参数表
Object paramter = param[1];
//获取查询结果处理器,类似于ResultSet
ResultHandler handler = (ResultHandler)param[3];
//获取具体被拦截的方法
Method method = arg0.getMethod();
//获取执行器,类似Statement
Executor target = (Executor) arg0.getTarget();
//通过MappedStatement获取的sql语句(不论是定义的注解或文件)
BoundSql bSql = mStatement.getBoundSql(paramter);
//将获取到的sql语句进行预处理
String pageSql = this.HandleSqlColumn(bSql.getSql(), paramter);
//定义一个新的sql,替换在配置文件或注解中的sql
BoundSql pageBoundSql = new BoundSql(mStatement.getConfiguration(), pageSql, bSql.getParameterMappings(), paramter);
//定义一个缓存,当执行查询后,会将查询结果存储到一级缓存中
CacheKey cacheKey = target.createCacheKey(mStatement, paramter, RowBounds.DEFAULT, pageBoundSql);
//执行
List<Object> temp = target.query(mStatement, paramter, RowBounds.DEFAULT, handler, cacheKey, pageBoundSql);
System.out.println("执行拦截器");
return temp;
}
private String HandleSqlColumn(String sql, Object parame) {
return sql;
}
}
配置文件中
<!-- 配置拦截器插件 -->
<plugins>
<plugin interceptor="com.mfqh.interceptor.PageInterceptor"></plugin>
</plugins>
检测
可以发现:在整个查询过程中执行了两次拦截器来进行处理