• Mybatis之插件拦截


    参考:http://www.mybatis.org/mybatis-3/zh/configuration.html#plugins

    MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

    • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
    • ParameterHandler (getParameterObject, setParameters)
    • ResultSetHandler (handleResultSets, handleOutputParameters)
    • StatementHandler (prepare, parameterize, batch, update, query)

    这些类中方法的细节可以通过查看每个方法的签名来发现,或者直接查看 MyBatis 发行包中的源代码。 如果你想做的不仅仅是监控方法的调用,那么你最好相当了解要重写的方法的行为。 因为如果在试图修改或重写已有方法的行为的时候,你很可能在破坏 MyBatis 的核心模块。 这些都是更低层的类和方法,所以使用插件的时候要特别当心。

    通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可。

    例如拦截SQL执行时间的插件:

    package com.javartisan.mybatis.plugin;
    
    import com.jd.ad.datamill.utils.SqlHelper;
    import org.apache.ibatis.plugin.Invocation;
    import org.apache.ibatis.executor.statement.StatementHandler;
    import org.apache.ibatis.mapping.BoundSql;
    import org.apache.ibatis.plugin.*;
    import org.apache.ibatis.session.ResultHandler;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.sql.Statement;
    import java.util.Properties;
    
    @Intercepts(@Signature(type = StatementHandler.class, method = "query",
            args = {Statement.class, ResultHandler.class}))
    public class SqlInterceptor implements Interceptor {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(SqlInterceptor.class);
        private Properties properties;
    
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            Object target = invocation.getTarget();
    
            long startTime = System.currentTimeMillis();
            StatementHandler statementHandler = (StatementHandler) target;
            try {
                return invocation.proceed();
            } finally {
                long endTime = System.currentTimeMillis();
                long sqlCost = endTime - startTime;
    
                BoundSql boundSql = statementHandler.getBoundSql();
    
                String sql = SqlHelper.formatSql(boundSql);
    
                LOGGER.info("QuerySQL:[" + sql + "],执行耗时:[" + sqlCost + "ms]");
            }
        }
    
        @Override
        public Object plugin(Object target) {
            return Plugin.wrap(target, this);
        }
    
        @Override
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
    
    }
    

      

    重点部分:

              @Intercepts(@Signature(type = StatementHandler.class, method = "query",args = {Statement.class, ResultHandler.class}))

    其中Signature为设置拦截条件,type表示要拦截的类型,method表示要拦截的方法,是type中的一个方法;args为该方法的参数;

    注意:type类型必须是Mybatis支持的类型,否则无法拦截!!!!

  • 相关阅读:
    第十七章 高级PERL技巧
    单例模式的优缺点
    饿汉式单例模式和懒汉式单例模式
    设计模式之设计原则
    Perl Socket 简单例子
    第16章 进程管理
    Map接口之HashSet、Hashtable、LinkedHashMap、TreeMap、WeakHashMap、IdentityHashMap、EnumMa
    Map接口之HashSet、Hashtable、LinkedHashMap、TreeMap、WeakHashMap、IdentityHashMap、EnumMa
    设计模式相关知识
    行为型设计模式
  • 原文地址:https://www.cnblogs.com/leodaxin/p/10075926.html
Copyright © 2020-2023  润新知