MyBatis-Plus的多租户以及SqlParserFilter注意点

MyBatis-Plus 在使用多租户功能时、有些接口、我们并不想被多租户过滤、这个时候就用到了 SqlParserFilter sql解析过滤器
看了 MyBatis-Plus 一部分源码后得知、该过滤器的大致功能方向、以及用法

首先是配置 PaginationInterceptor 类、官方示例查看 多租户解析 PaginationInterceptor 继承 AbstractSqlParserHandler类、解析最重要的方法就在 AbstractSqlParserHandler 类的sqlParser方法中

   protected void sqlParser(MetaObject metaObject) {
        if (null != metaObject) {
            Object originalObject = metaObject.getOriginalObject();
            StatementHandler statementHandler = (StatementHandler)PluginUtils.realTarget(originalObject);
            metaObject = SystemMetaObject.forObject(statementHandler);
            
            //1、这一句就是SqlParserFilter的作用、如果SqlParserFilter不等于空、并且执行SqlParserFilter接口的doFilter
            // 方法的到的结果值为 true 的话就不往下执行了
            if (null != this.sqlParserFilter && this.sqlParserFilter.doFilter(metaObject)) {
                return;
            }
           //2、这个是用于@SqlParser注解的、如果@SqlParser注解值为 true 则不往下执行、这个是放在Mapper接口上的
            if (SqlParserHelper.getSqlParserInfo(metaObject)) {
                return;
            }
            //3、这里开始进行SQL解析  sqlParserList是解析链
            if (CollectionUtils.isNotEmpty(this.sqlParserList)) {
                statementHandler = metaObject.hasGetter("delegate") ? (StatementHandler)metaObject.getValue("delegate") : statementHandler;
                if (!(statementHandler instanceof CallableStatementHandler)) {
                    boolean sqlChangedFlag = false; //标记是否修改过Sql
                    String originalSql = (String)metaObject.getValue("delegate.boundSql.sql");
                    Iterator var6 = this.sqlParserList.iterator();
                    //循环解析了
                    while(var6.hasNext()) {
                        ISqlParser sqlParser = (ISqlParser)var6.next();
                        if (sqlParser.doFilter(metaObject, originalSql)) {
                            SqlInfo sqlInfo = sqlParser.parser(metaObject, originalSql);
                            if (null != sqlInfo) {
                                originalSql = sqlInfo.getSql();
                                sqlChangedFlag = true;
                            }
                        }
                    }

                    if (sqlChangedFlag) {
                        metaObject.setValue("delegate.boundSql.sql", originalSql);
                    }
                }
            }
        }

    }

大概原理也就和上面的类似、如果有兴趣还可以把多租户的TenantSqlParser 扩展一下、扩展成只拦截删除标识的、这样也可以做到全局的删除标识自动追加、不过有点遗憾的就是 SqlParserFilter 是统一设置过滤的、并不是根据一个个的 SqlParser 进行有规范的过滤、当然TenantSqlParser 也是有自己的处理规范的、但是如果改写 TenantSqlParser 后两个处理规范多多少少会冲突、有些接口是注定需要手动追加的,可参考 MyBatis-Plus根据多租户扩展删除标识功能

注意点 SqlParserFilter的doFilter方法中,如果使用MetaObject类的getId方法去判断该方法是过滤还是放行的时候、对比的方法必须是Mapper方法,因为MetaObject的getId方法得到的都是Mapper层的方法

你可能感兴趣的:(MyBatis-Plus)