mybatis如何实现SQL查询拦截修改

  介绍

这篇文章将为大家详细讲解有关mybatis如何实现SQL查询拦截修改,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

<强>前言

截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法。

mybatis拦截器设计的一个初衷就是为了供用户在某些时候可以实现自己的逻辑而不必去动mybatis固有的逻辑。比如我想针对所有的SQL执行某个固定的操作,针对SQL查询执行安全检查,或者记录相关SQL查询日志等等。

mybatis为我们提供了一个拦截器接口,可以实现自定义的拦截器。

, public  interface  Interceptor  {   ,Object 拦截(Invocation 调用),throws  Throwable;   ,Object 插件(Object 目标);   ,void 找(Properties 属性);   }

<>强接口中包含了三个方法定义

拦截方法为具体的拦截对象的处理方法,传入的调用包含了拦截目标类的实力,拦截的方法和方法的入参数组。使用调用的proc执行原函数。

插件中执行判断是否要进行拦截进,如果不需要拦截,直接返回目标,如果需要拦截则调用插件类中的包装静态方法,如果当前拦截器实现了任意接口,则返回一个代理对象,否则直接返回(回忆代理模式的设计)。代理对象实际是一个插件类实例,它实现了InvocationHandler接口,InvocationHandler接口仅包含调用方法用于回调方法。

当执行代理对象的接口方法时,会调用插件的调用方法,它会把要执行的对象,方法和参数打包成调用对象传给拦截器的拦截方法.Invocation定义了一个proc方法,用于执行被拦截的原方法。

<强>插件类定义

public  class  Plugin  implements  InvocationHandler  {   ,   ,private  Object 目标;   ,private  Interceptor 拦截;   ,private 地图,Set>, signatureMap;   ,   ,private 插件(Object 目标,Interceptor 拦截器,,地图,Set>, signatureMap), {   时间=this.target 才能;目标;   this.interceptor 才能=,拦截器;   时间=this.signatureMap 才能;signatureMap;   ,}   ,   ,public  static  Object 包装(Object 目标,Interceptor 拦截器),{   地图,才能,Set>, signatureMap =, getSignatureMap(拦截器);   Class 才能;type =, target.getClass ();   类[],才能interfaces =, getAllInterfaces(类型,signatureMap);   if 才能;(interfaces.length 祝辞,0),{   ,,return  Proxy.newProxyInstance (   ,,,,type.getClassLoader (),   ,,,,的接口,   ,,,,new 插件(拦截器,目标,还以为;signatureMap));   ,,}   return 才能;目标;   ,}   ,   ,public  Object 调用(Object 代理,,Method 方法,对象[],args), throws  Throwable  {   try {才能   ,,Set  methods =, signatureMap.get (method.getDeclaringClass ());   ,,if  (methods  !=, null ,,, methods.contains(方法),{   ,,,return  interceptor.intercept (new 调用(目标,方法,args));   ,,}   ,,return  method.invoke(目标,,args);   ,,},catch  (Exception  e), {   ,,throw  ExceptionUtil.unwrapThrowable (e);   ,,}   ,}   ,   ,private  static 地图,Set>, getSignatureMap (Interceptor 拦截器),{   Intercepts 才能;interceptsAnnotation =, interceptor.getClass () .getAnnotation (Intercepts.class);   if 才能;(interceptsAnnotation ==, null), {,//issue  # 251   ,,throw  new  PluginException (“No  @Intercepts  annotation  was  found 拷贝interceptor “, +, interceptor.getClass () . getname ()),,,,   ,,}   签名才能[],sigs =, interceptsAnnotation.value ();   地图,才能,Set>, signatureMap =, new  HashMap,, Set> ();   for 才能;(Signature  sig :团体),{   ,,Set  methods =, signatureMap.get (sig.type ());   ,,if  (methods ==, null), {   ,,,methods =, new  HashSet ();   ,,,signatureMap.put (sig.type(),方法);   ,,}   ,,try  {   ,,,Method  Method =, sig.type () .getMethod (sig.method (),, sig.args ());   ,,,methods.add(方法);   ,,},catch  (NoSuchMethodException  e), {   ,,,throw  new  PluginException (“Could  not  find  method 提醒“,+,sig.type (), +,“, named “, +, sig.method(), +,“只原因:,“,+,e, e);   ,,}   ,,}   return 才能;signatureMap;   ,}   ,   ,private  static 类[],getAllInterfaces (Class 类型,地图,Set>, signatureMap), {   ,,Set> interfaces =, new  HashSet> ();   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

mybatis如何实现SQL查询拦截修改