若依mybatis自定义拦截sql

  1. 拦截器
@Slf4j
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class DataAuthInterceptor implements Interceptor {
  //关键字
 private  String dataAuthScope = "xxx";

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql;

        // 通过MetaObject访问对象的属性
        MetaObject metaObject = MetaObject.forObject(
                statementHandler,
                SystemMetaObject.DEFAULT_OBJECT_FACTORY,
                SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,
                new DefaultReflectorFactory());
        // 获取成员变量mappedStatement
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        //验证是否需要拦截
        if (!needToBeIntercepted(mappedStatement.getId())) {
            return invocation.proceed();
        }
        
        boundSql = statementHandler.getBoundSql();
        //获取到原始sql语句
        String sql = boundSql.getSql();
        //多个空格替换为一个空格
         sql  = sql.replaceAll("\\s{1,}", " ");
        //如果查询关键字可以进行数据权限过滤
        if (sql.indexOf(dataAuthScope) >= 0) {
            //权限sql
            String dataAuthSql = "xxx";
            //关键字替换
            String replace = sql.replace(dataAuthScope, dataAuthSql.toString());

            log.debug("=====DataAuth sql rewrite:  sql:={}", replace);

            //通过反射修改sql语句
            Field field = boundSql.getClass().getDeclaredField("sql");
            field.setAccessible(true);
            field.set(boundSql, replace);

        }

        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }

    /**
     * 判断是否需要被拦截
     */
    private boolean needToBeIntercepted(String methodFullPath) throws ClassNotFoundException {
        String classFullPath = methodFullPath.substring(0, methodFullPath.lastIndexOf("."));
        String methodSimpleName = methodFullPath.substring(methodFullPath.lastIndexOf(".") + 1);
        if (methodSimpleName.endsWith("_COUNT")){//分页处理
            methodSimpleName = methodSimpleName.replace("_COUNT", "");
        }
        for (Method method : Class.forName(classFullPath).getDeclaredMethods()) {
            if (method.getName().equals(methodSimpleName)) {
                if (  method.getAnnotation(MapperDataScope.class) != null) {
                    return true;
                }
            }
        }
        return false;
    }
  1. 新建配置类
/**
 * mybatis自定义拦截器
 */
@Configuration
public class MybatisInterceptorAutoConfiguration {


    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;

    /**
     * 只会执行一次
     * 顺序:Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
     */
    @PostConstruct
    public void addMysqlInterceptor() {
        //创建自定义mybatis拦截器,添加到chain的最后面
        DataAuthInterceptor interceptor = new DataAuthInterceptor();
        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
            org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();
            //自己添加
            configuration.addInterceptor(interceptor);
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容