mybatis-plus多租户多层子查询拼接租户id

在将项目改成多租户模式时,因为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 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 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 ifExpression=expressionList.getExpressions();

                for (Expression e:ifExpression){

                    operateExpression(e);

                }

            }

        }

    }

}

然后在配置文件调用

@Bean

public PaginationInterceptor paginationInterceptor() {

    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();

    paginationInterceptor.setLocalPage(true);// 开启 PageHelper 的支持

    /*

    * 【测试多租户】 SQL 解析处理拦截器

    * 这里固定写成住户 1 实际情况你可以从cookie读取,因此数据看不到 【 麻花藤 】 这条记录( 注意观察 SQL )

    */

    List 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多租户多层子查询拼接租户id)