• 【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
  • 相关阅读:
    django中的分页管理
    python 时间字符串和时间戳之间的转换
    随机生成英文字母,并且统计频数
    html 中a标签的问题(无反应,跳转,调用方法)
    oracle sid,instance_name,db_name,oracle_sid之间的关系
    备份
    修改yum源
    sql基本语法
    第二章 shell编程基础
    第一章 初识shell程序
  • 原文地址:https://www.cnblogs.com/shangxiaofei/p/11487852.html
Copyright © 2020-2023  润新知