数据库
首页 > 数据库> > springboot sql注解拦截器

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);

 

标签:拦截器,springboot,mappedStatement,getId,method,sql,StatementHandler,class
来源: https://www.cnblogs.com/ch94/p/16385469.html