zoukankan      html  css  js  c++  java
  • 【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
  • 相关阅读:
    IDEA常用快捷指令整理
    Python dict 字典
    内联函数
    【MFC】编辑框 CEdit Ctrl控件自动换行设置
    mysql 多sql文件恢复方案
    Linux: 用64位的系统,能编译32位的程序吗?
    C++ 遍历数组
    工业现场传感器传感器为什么采用电流形式输出?
    【转】电磁阀、电磁铁的工作原理说明
    PCB板强弱电隔离距离不够导致损坏和问题检查记录
  • 原文地址:https://www.cnblogs.com/shangxiaofei/p/11487852.html
Copyright © 2011-2022 走看看