(六)mybatis拦截器
首先拦截器可以拦截mybatis四大核心对象:
StatementHandler,ParameterHandler,ResultSetHandler,Executor,具体拦截时根据需求拦截一部分方法
写拦截器分为三步:
1.定义拦截器实现拦截器接口,说明拦截什么
@Intercepts({ //说明拦截什么 @Signature(type= StatementHandler.class, method = "query",args = {Statement.class, ResultHandler.class}) })
2.编写拦截器方法
public class MyInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { Object proceed = invocation.proceed(); //放行方法,拿到返回值 System.out.println("拦截方法"+proceed); return proceed; } @Override //将拦截器之中定义增强功能和原来的核心功能合并, public Object plugin(Object target) { Object wrap = Plugin.wrap(target, this); //合并 System.out.println(wrap); return wrap; } @Override public void setProperties(Properties properties) { System.out.println("拿到的属性:"+properties); } }
3.进行配置
<plugins> <plugin interceptor="Interceptors.MyInterceptor"> <property name="name" value="张三"/> <property name="loves" value="作画"/> </plugin> </plugins>
这样,当你运行指定方法时,他就会进行拦截,拦截分为两部分,一部分是setProperties和plugin方法,在发送请求的时候拦截,获取到值之后,返回的路上,用intercept拦截。
另外如果有多个拦截器,按照配置的顺序进行拦截。
下面是一个简单的拦截器实现:拦截查询时设置参数的方法,将参数改变为2:
注解:
//自定义拦截器 @Intercepts({ //说明拦截什么 // @Signature(type= StatementHandler.class, method = "query",args = {Statement.class, ResultHandler.class}) @Signature(type= StatementHandler.class, method = "parameterize",args = {Statement.class}) })
拦截方法:
public Object intercept(Invocation invocation) throws Throwable { Object target= invocation.getTarget(); //目标方法,具体执行的方法 System.out.println("目标对象"+target); //将目标方法包装,获取之后的产物 MetaObject metaObject = SystemMetaObject.forObject(target); //内置方法 //拦截,将方法的参数变为2 metaObject.setValue("parameterHandler.parameterObject",2); //获取参数值,验证 Object object = metaObject.getValue("parameterHandler.parameterObject"); System.out.println("拿到的参数值:"+object); Object proceed = invocation.proceed(); //放行,执行查询方法,拿到返回值 return proceed; }
这里需要注意:
1.proceed()是放行方法,放行之后就会执行查询操作,所以拦截操作要在这个方法之前进行,注意拦截时机。
2.mybatis底层用parameterize设置参数,query只是查询