• springboot sql注解拦截器


    @Component
    @Intercepts({
            @Signature(
                    type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class
            })
    })
    public class SqlInterceptor implements Interceptor {
        
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            // 方法一
            StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
            MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
                    SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
            /*
             * 先拦截到RoutingStatementHandler,里面有个StatementHandler类型的delegate变量,其实现类是BaseStatementHandler,
             * 然后就到BaseStatementHandler的成员变量mappedStatement
             */
            MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
            //id为执行的mapper方法的全路径名
    //        String id = mappedStatement.getId();
            //sql语句类型 select、delete、insert、update
    //        String sqlCommandType = mappedStatement.getSqlCommandType().toString();
            BoundSql boundSql = statementHandler.getBoundSql();
    
            //获取到原始sql语句
            String sql = boundSql.getSql();
            String mSql = sql;
    
            //TODO 修改位置
    
            //注解逻辑判断  添加注解了才拦截
            Class<?> classType = Class.forName(mappedStatement.getId().substring(0, mappedStatement.getId().lastIndexOf(".")));
            String mName = mappedStatement.getId().substring(mappedStatement.getId().lastIndexOf(".") + 1, mappedStatement.getId().length());
            for (Method method : classType.getDeclaredMethods()) {
                if (method.isAnnotationPresent(SqlAnnotation.class) && mName.equals(method.getName())) {
                    SqlAnnotation interceptorAnnotation = method.getAnnotation(SqlAnnotation.class);
                    if (interceptorAnnotation.flag()) {
                        //可以在此处修改sql,用字符串拼接即可
                        SysAdmin loginAdmin = (SysAdmin)SecurityUtils.getSubject().getPrincipal();
                        //数据权限  admin系统权限  agent代理权限 mf厂商权限  decorate装饰公司权限
                        System.err.println("============sql拦截后的操作:"+mSql+"===============");
                        
                    }
                }
            }
            //通过反射修改sql语句
            Field field = boundSql.getClass().getDeclaredField("sql");
            field.setAccessible(true);
            field.set(boundSql, mSql);
            return invocation.proceed();
        }
        
        @Override
        public Object plugin(Object target) {
            if (target instanceof StatementHandler) {
                return Plugin.wrap(target, this);
            } else {
                return target;
            }
        }
        
        @Override
        public void setProperties(Properties properties) {
    
        }
    }
    /**
     * 定义了一个方法层面的注解,实现局部指定拦截
     * 
     * @author chen
     *
     */
    @Target({ElementType.METHOD,ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface SqlAnnotation {
        
        boolean flag() default true;
        
    }
       在mapper上添加注解即可
    @SqlAnnotation(flag = true) List<Map<String,Object>> getListPage(DecCompany company);
  • 相关阅读:
    9.2模拟题解
    NOI1995 石子合并
    NOIP2012 借教室
    织梦内页读取栏目banner图
    mysql数据库版本引发的问题
    简单修改hosts文件加快打开网页速度
    详细剖析电脑hosts文件的作用和修改
    内部标签样式
    织梦让当前的子栏目拥有特殊的样式
    织梦获取单个顶级栏目名
  • 原文地址:https://www.cnblogs.com/ch94/p/16385469.html
Copyright © 2020-2023  润新知