• 使用mybatis插件拦截SQL


    1、定义注解,只拦截有注解的Mapper方法

    package com.sgm.qms.system.aop;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 导入记录日志
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface ExportLogger {
    }

    2、定义拦截器

    package com.sgm.qms.system.aop;
    
    import com.sgm.qms.common.controller.BaseController;
    import com.sgm.qms.common.utils.ContextUtil;
    import com.sgm.qms.system.entity.Employee;
    import org.apache.ibatis.cache.CacheKey;
    import org.apache.ibatis.executor.Executor;
    import org.apache.ibatis.mapping.BoundSql;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.mapping.ParameterMapping;
    import org.apache.ibatis.plugin.*;
    import org.apache.ibatis.reflection.MetaObject;
    import org.apache.ibatis.session.Configuration;
    import org.apache.ibatis.session.ResultHandler;
    import org.apache.ibatis.session.RowBounds;
    import org.apache.ibatis.type.TypeHandlerRegistry;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.http.HttpServletRequest;
    import java.lang.reflect.Method;
    import java.text.DateFormat;
    import java.util.*;
    import java.util.regex.Matcher;
    
    
    @Intercepts({
            @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
            @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
    })
    @Component
    public class ExportLoggerInterceptor extends BaseController implements Interceptor {
    
        private static final Logger logger = LoggerFactory.getLogger(ExportLoggerInterceptor.class);
    
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            try {
                MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
    
                //1.获取方法全路径
                String methodNameSpace = mappedStatement.getId();
                int i = methodNameSpace.lastIndexOf(".");
                String className = methodNameSpace.substring(0, i);
                String methodName = methodNameSpace.substring(++i);
                Class<?> mapperClass = Class.forName(className);
                Method[] declaredMethods = mapperClass.getDeclaredMethods();
                for (Method method : declaredMethods) {
                    if(methodName.equals(method.getName())) {
                        ExportLogger exportLogger = method.getAnnotation(ExportLogger.class);
                        if(exportLogger != null) {
                            Object parameter = null;
                            if (invocation.getArgs().length > 1) {
                                parameter = invocation.getArgs()[1];
                            }
                            BoundSql boundSql = mappedStatement.getBoundSql(parameter);
                            Configuration configuration = mappedStatement.getConfiguration();
                            String sql = getSql(configuration, boundSql);// todo 此处将信息存入数据即可
                        }
                    }
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
            return invocation.proceed();
        }
    
    
        @Override
        public Object plugin(Object target) {
            return target instanceof Executor ? Plugin.wrap(target, this) : target;
        }
    
        @Override
        public void setProperties(Properties properties) {}
    
    
        private static String getSql(Configuration configuration, BoundSql boundSql) {
            String sql = showSql(configuration, boundSql);
            return sql;
        }
    
        private static String getParameterValue(Object obj) {
            String value = null;
            if (obj instanceof String) {
                value = "'" + obj.toString() + "'";
            } else if (obj instanceof Date) {
                DateFormat formatter = DateFormat.getDateTimeInstance(
                        DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
                value = "'" + formatter.format(new Date()) + "'";
            } else {
                if (obj != null) {
                    value = obj.toString();
                } else {
                    value = "";
                }
    
            }
            return value;
        }
    
        private static String showSql(Configuration configuration, BoundSql boundSql) {
            Object parameterObject = boundSql.getParameterObject();
            List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
            String sql = boundSql.getSql().replaceAll("[\s]+", " ");
            if (!parameterMappings.isEmpty() && parameterObject != null) {
                TypeHandlerRegistry typeHandlerRegistry = configuration
                        .getTypeHandlerRegistry();
                if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                    sql = sql.replaceFirst("\?",
                            Matcher.quoteReplacement(getParameterValue(parameterObject)));
    
                } else {
                    MetaObject metaObject = configuration
                            .newMetaObject(parameterObject);
                    for (ParameterMapping parameterMapping : parameterMappings) {
                        String propertyName = parameterMapping.getProperty();
                        if (metaObject.hasGetter(propertyName)) {
                            Object obj = metaObject.getValue(propertyName);
                            sql = sql.replaceFirst("\?", Matcher.quoteReplacement(getParameterValue(obj)));
                        } else if (boundSql.hasAdditionalParameter(propertyName)) {
                            Object obj = boundSql
                                    .getAdditionalParameter(propertyName);
                            sql = sql.replaceFirst("\?", Matcher.quoteReplacement(getParameterValue(obj)));
                        } else {
                            sql = sql.replaceFirst("\?", "缺失");
                        }//打印出缺失,提醒该参数缺失并防止错位
                    }
                }
            }
            return sql;
        }
    }

    3、向容器添加插件

       a springboot项目直接在拦截器类上加 @Component 注解 或 使用 @Bean 注入容器

       b 非springboot项目在mybatis的配置文件加入 plugin 就行

    只要你不觉得尴尬,那尴尬的就是别人
  • 相关阅读:
    6美元进公园随便挖钻石

    别了,四方
    九种感觉叫爱情,你遭遇过哪一种?(转)
    我提出辞职,老板竟然让我做选择题(转)
    五大绝招让你永远是人才
    人生必读十大启迪(1):生活到底是什么
    创业95%失败不是因项目本身
    穷国和富国差别在哪里
    一个丑女的感情独白
  • 原文地址:https://www.cnblogs.com/wujiaxing/p/15109455.html
Copyright © 2020-2023  润新知