美文网首页
对mybatis-plus多租户的select部分拼接租户id

对mybatis-plus多租户的select部分拼接租户id

作者: qiuzhenjie | 来源:发表于2020-08-20 10:39 被阅读0次

在将项目改成多租户模式时,因为mybatis-plus自带的功能只会拼接left 、from和where后面的表或子查询添加租户id。想要将selete部分的子查询拼接租户id,必须重写TenantSqlParser类的processPlainSelect(PlainSelect plainSelect)方法,代码如下:

public class TestTenantSqlParser extends TenantSqlParser {
    @Override
    protected void processPlainSelect(PlainSelect plainSelect) {
        // SELECT 至 FROM 中的嵌套查询
        List<SelectItem> selectItemList = plainSelect.getSelectItems();
        for (SelectItem selectItem : selectItemList) {
            if (selectItem instanceof SelectExpressionItem) {
                SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem;
                if (!(selectExpressionItem.getExpression() instanceof Column)) {
                    // 处理 column select 嵌套部分
                    operateExpression(selectExpressionItem.getExpression());
                }
            }
        }
        processPlainSelect(plainSelect, false);
    }

    private void operateExpression(Expression expression){
        if (expression instanceof SubSelect){
            SubSelect subSelect = (SubSelect) expression;
            PlainSelect plainSelect = (PlainSelect) subSelect.getSelectBody();
            processSelectBody(plainSelect);
        }
        else if (expression instanceof Parenthesis){
            Parenthesis parenthesis= (Parenthesis) expression;
            operateExpression(parenthesis.getExpression());
        }else if (expression instanceof CaseExpression) { //处理case when
            CaseExpression caseExpression= (CaseExpression) expression;
            caseExpression.getWhenClauses();
            List<Expression> whenClauses = caseExpression.getWhenClauses();
            for (Expression e : whenClauses) {
                if (e instanceof WhenClause){
                    WhenClause whenClause= (WhenClause) e;
                    operateExpression(whenClause.getThenExpression());
                }
            }
        }else if (expression instanceof Function){//处理IFNULL
            Function function= (Function) expression;
            if ("IFNULL".equals(function.getName())){
                ExpressionList expressionList=function.getParameters();
                List<Expression> ifExpression=expressionList.getExpressions();
                for (Expression e:ifExpression){
                    operateExpression(e);
                }
            }
        }
    }
}

然后在配置文件调用

@Bean
public PaginationInterceptor paginationInterceptor() {
    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
    paginationInterceptor.setLocalPage(true);// 开启 PageHelper 的支持
    /*
     * 【测试多租户】 SQL 解析处理拦截器<br>
     * 这里固定写成住户 1 实际情况你可以从cookie读取,因此数据看不到 【 麻花藤 】 这条记录( 注意观察 SQL )<br>
     */
    List<ISqlParser> sqlParserList = new ArrayList<>();
    /**
      *此处调用重写的类
      *
      */
    TestTenantSqlParser tenantSqlParser = new TestTenantSqlParser ();
    tenantSqlParser.setTenantHandler(new TenantHandler() {
        @Override
        public Expression getTenantId() {
            return new LongValue(1L);
        }

        @Override
        public String getTenantIdColumn() {
            return "tenant_id";
        }

        @Override
        public boolean doTableFilter(String tableName) {
            // 这里可以判断是否过滤表
            /*
            if ("user".equals(tableName)) {
                return true;
            }*/
            return false;
        }
    });
    sqlParserList.add(tenantSqlParser);
    paginationInterceptor.setSqlParserList(sqlParserList);
    paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
        @Override
        public boolean doFilter(MetaObject metaObject) {
            MappedStatement ms = PluginUtils.getMappedStatement(metaObject);
            // 过滤自定义查询此时无租户信息约束【 麻花藤 】出现
            if ("com.baomidou.springboot.mapper.UserMapper.selectListBySQL".equals(ms.getId())) {
                return true;
            }
            return false;
        }
    });
    return paginationInterceptor;
}

相关文章

网友评论

      本文标题:对mybatis-plus多租户的select部分拼接租户id

      本文链接:https://www.haomeiwen.com/subject/cdksjktx.html