• 【mybatis源码学习】mybatis的插件功能


    一、mybatis的插件功能可拦截的目标

    org.apache.ibatis.executor.parameter.ParameterHandler
    org.apache.ibatis.executor.resultset.ResultSetHandler
    org.apache.ibatis.executor.statement.StatementHandler
    org.apache.ibatis.executor.Executor

    二、Mybatis的插件功能接入步骤

    1、实现接口:org.apache.ibatis.plugin.Interceptor

    2、实现类上需要添加注解@Intercepts和@Signature 用于描述要进行拦截的类接口和方法

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface Intercepts {
      Signature[] value(); //要拦截的方法信息描述
    }
    
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface Signature {
      Class<?> type(); //要拦截的类的描述(接口)
    
      String method();//要拦截的方法名
    
      Class<?>[] args();//要拦截的方法名的参数列表的类型
    }
    View Code

    3、将实现的Interceptor的类的对象,注入到Configuration的interceptorChain中

    三、编写一个打印当前执行sql语句的插件案例

    1、分析

    依据mybatis的执行计划,StatementHandler 有一个方法 BoundSql getBoundSql(),其调用时机是向数据库申请连接,并向sql语句绑定参数时,从其内部获取sql语句。

    故插件需要对StatementHandler进行拦截,并在其执行 getBoundSql语句时,从返回结果中获取sql语句,并打印

    2、注意点

    mybatis的插件功能使用的前提是对mybatis框架非常熟悉。

    3、案例

    @Intercepts(value = {@Signature(type = StatementHandler.class,method = "prepare",args = {Connection.class,Integer.class})})
    public class SqlPrintInterceptor implements Interceptor {
    
        /**
         * 决定那个对象需要进行代理拦截
         * @param target
         * @return
         */
        @Override
        public Object plugin(Object target) {
            if(target instanceof StatementHandler){
                return Plugin.wrap(target, this);
            }
            return target;
        }
    
        /**
         * 执行代理的逻辑增强
         * @param invocation
         * @return
         * @throws Throwable
         */
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
             Object obj=invocation.proceed();
             RoutingStatementHandler handler= (RoutingStatementHandler) invocation.getTarget();
             System.out.println("current do sql=["+handler.getBoundSql().getSql()+"]");
            return obj;
        }
    
        /**
         * 设置当前代理的配置
         * @param properties
         */
        @Override
        public void setProperties(Properties properties) {
    
        }
    }
    View Code
    interceptorChain
  • 相关阅读:
    XHTML学习笔记 Part3:核心属性
    XHTML学习笔记 Part2:核心元素
    XHTML学习笔记 part1
    北航非全日制-软件学院考研攻略(经验仅来自于2019年,2020年招生简章有变动,需谨慎)
    为什么能抓到网站https传输的明文密码?------顺便说说“知乎”和“支付宝”的安全性对比
    JetBrain系列学生免费授权
    印象笔记模板推荐使用
    测试用例评审总结与规范
    Django入门
    Django在根据models生成数据库表时报 __init__() missing 1 required positional argument: 'on_delete'
  • 原文地址:https://www.cnblogs.com/shangxiaofei/p/11487852.html
Copyright © 2020-2023  润新知