/** * Copyright (c) 2011-2020, hubin (jobob@qq.com). *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at *
* http://www.apache.org/licenses/LICENSE-2.0 *
* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.baomidou.mybatisplus.plugins.tenancy; import java.util.ArrayList; import java.util.List; import com.baomidou.mybatisplus.parser.AbstractSqlParser; import com.baomidou.mybatisplus.parser.SqlInfo; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.BinaryExpression; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.StringValue; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.InExpression; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.delete.Delete; import net.sf.jsqlparser.statement.insert.Insert; import net.sf.jsqlparser.statement.select.FromItem; import net.sf.jsqlparser.statement.select.Join; import net.sf.jsqlparser.statement.select.LateralSubSelect; import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.SelectBody; import net.sf.jsqlparser.statement.select.SelectExpressionItem; import net.sf.jsqlparser.statement.select.SetOperationList; import net.sf.jsqlparser.statement.select.SubJoin; import net.sf.jsqlparser.statement.select.SubSelect; import net.sf.jsqlparser.statement.select.ValuesList; import net.sf.jsqlparser.statement.select.WithItem; import net.sf.jsqlparser.statement.update.Update; /** *
* 租户 SQL 解析 *
* * @author hubin * @since 2017-06-20 */ public class TenancySqlParser extends AbstractSqlParser { private TenantInfo tenantInfo; @Override public SqlInfo optimizeSql(String sql) { //logger.debug("old sql:{}", sql); Statement stmt = null; try { stmt = CCJSqlParserUtil.parse(sql); } catch (JSQLParserException e) { //logger.debug("解析", e); //logger.error("解析sql[{}]失败\n原因:{}", sql, e.getMessage()); //如果解析失败不进行任何处理防止业务中断 return null; } if (stmt instanceof Insert) { processInsert((Insert) stmt); } else if (stmt instanceof Select) { processSelectBody(((Select) stmt).getSelectBody()); } else if (stmt instanceof Update) { processUpdate((Update) stmt); } //logger.debug("new sql:{}", stmt); SqlInfo sqlInfo = SqlInfo.newInstance(); sqlInfo.setSql(stmt.toString()); return sqlInfo; } /** ** select 语句处理 *
*/ public void processSelectBody(SelectBody selectBody) { if (selectBody instanceof PlainSelect) { processPlainSelect((PlainSelect) selectBody); } else if (selectBody instanceof WithItem) { WithItem withItem = (WithItem) selectBody; if (withItem.getSelectBody() != null) { processSelectBody(withItem.getSelectBody()); } } else { SetOperationList operationList = (SetOperationList) selectBody; if (operationList.getSelects() != null && operationList.getSelects().size() > 0) { List* insert 语句处理 *
*/ public void processInsert(Insert insert) { if (doTableFilter( insert.getTable().getName() )) { insert.getColumns().add(new Column(this.tenantInfo.getTenantIdColumn())); if (insert.getSelect() != null) { processPlainSelect((PlainSelect) insert.getSelect().getSelectBody(), true); } else if (insert.getItemsList() != null) { ((ExpressionList) insert.getItemsList()).getExpressions().add(new StringValue("," + this.tenantInfo.getTenantId() + ",")); } else { // throw new RuntimeException("无法处理的 sql"); } } } /** ** update 语句处理 *
*/ public void processUpdate(Update update) { //获得where条件表达式 Expression where = update.getWhere(); EqualsTo equalsTo = new EqualsTo(); if (where instanceof BinaryExpression) { equalsTo.setLeftExpression(new Column(this.tenantInfo.getTenantIdColumn())); equalsTo.setRightExpression(new StringValue("," + tenantInfo.getTenantId() + ",")); AndExpression andExpression = new AndExpression(equalsTo, where); update.setWhere(andExpression); } else { equalsTo.setLeftExpression(new Column(this.tenantInfo.getTenantIdColumn())); equalsTo.setRightExpression(new StringValue("," + tenantInfo.getTenantId() + ",")); update.setWhere(equalsTo); } } /** ** delete 语句处理 *
*/ public void processDelete(Delete delete) { } /** * 处理PlainSelect */ public void processPlainSelect(PlainSelect plainSelect) { processPlainSelect(plainSelect, false); } /** * 处理PlainSelect * * @param plainSelect * @param addColumn 是否添加租户列,insert into select语句中需要 */ public void processPlainSelect(PlainSelect plainSelect, boolean addColumn) { FromItem fromItem = plainSelect.getFromItem(); if (fromItem instanceof Table) { Table fromTable = (Table) fromItem; if (doTableFilter(fromTable.getName())) { plainSelect.setWhere(builderExpression(plainSelect.getWhere(), fromTable)); if (addColumn) plainSelect.getSelectItems().add(new SelectExpressionItem(new Column("'" + this.tenantInfo.getTenantId() + "'"))); } } else { processFromItem(fromItem); } List