|
@@ -41,8 +41,9 @@ import org.apache.ibatis.session.RowBounds;
|
|
|
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.SQLException;
|
|
|
-import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.Collection;
|
|
|
+import java.util.Collections;
|
|
|
import java.util.Deque;
|
|
|
import java.util.LinkedList;
|
|
|
import java.util.List;
|
|
@@ -235,38 +236,48 @@ public class TenantLineInnerInterceptor extends JsqlParserSupport implements Inn
|
|
|
* 处理 PlainSelect
|
|
|
*/
|
|
|
protected void processPlainSelect(PlainSelect plainSelect) {
|
|
|
- FromItem fromItem = plainSelect.getFromItem();
|
|
|
-
|
|
|
//#3087 github
|
|
|
List<SelectItem> selectItems = plainSelect.getSelectItems();
|
|
|
if (CollectionUtils.isNotEmpty(selectItems)) {
|
|
|
selectItems.forEach(this::processSelectItem);
|
|
|
}
|
|
|
|
|
|
- // #I4FP6E gitee:右连接查询时,where 条件需要过滤
|
|
|
- List<Table> rightJointTables;
|
|
|
+ // 处理 where 中的子查询
|
|
|
+ Expression where = plainSelect.getWhere();
|
|
|
+ processWhereSubSelect(where);
|
|
|
+
|
|
|
+ // 处理 fromItem
|
|
|
+ FromItem fromItem = plainSelect.getFromItem();
|
|
|
+ Table mainTable = processFromItem(fromItem);
|
|
|
+
|
|
|
+ // 处理 join
|
|
|
List<Join> joins = plainSelect.getJoins();
|
|
|
if (CollectionUtils.isNotEmpty(joins)) {
|
|
|
- rightJointTables = processJoins(joins);
|
|
|
- }else {
|
|
|
- rightJointTables = new ArrayList<>();
|
|
|
+ mainTable = processJoins(mainTable, joins);
|
|
|
}
|
|
|
|
|
|
- Expression where = plainSelect.getWhere();
|
|
|
- processWhereSubSelect(where);
|
|
|
+ // 当有 mainTable 时,进行 where 条件追加
|
|
|
+ if (mainTable != null) {
|
|
|
+ plainSelect.setWhere(builderExpression(where, Collections.singletonList(mainTable)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Table processFromItem(FromItem fromItem) {
|
|
|
+ Table mainTable = null;
|
|
|
+ // 无 join 时的处理逻辑
|
|
|
if (fromItem instanceof Table) {
|
|
|
Table fromTable = (Table) fromItem;
|
|
|
- boolean needIgnore = tenantLineHandler.ignoreTable(fromTable.getName());
|
|
|
- if (needIgnore) {
|
|
|
- plainSelect.setWhere(builderExpression(where, null, rightJointTables));
|
|
|
- }else {
|
|
|
- //#1186 github
|
|
|
- plainSelect.setWhere(builderExpression(where, fromTable, rightJointTables));
|
|
|
+ if (!tenantLineHandler.ignoreTable(fromTable.getName())) {
|
|
|
+ mainTable = fromTable;
|
|
|
}
|
|
|
+ } else if (fromItem instanceof SubJoin) {
|
|
|
+ // SubJoin 类型则还需要添加上 where 条件
|
|
|
+ mainTable = processSubJoin((SubJoin) fromItem);
|
|
|
} else {
|
|
|
- processFromItem(fromItem);
|
|
|
+ // 处理下 fromItem
|
|
|
+ processOtherFromItem(fromItem);
|
|
|
}
|
|
|
-
|
|
|
+ return mainTable;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -294,7 +305,7 @@ public class TenantLineInnerInterceptor extends JsqlParserSupport implements Inn
|
|
|
return;
|
|
|
}
|
|
|
if (where instanceof FromItem) {
|
|
|
- processFromItem((FromItem) where);
|
|
|
+ processOtherFromItem((FromItem) where);
|
|
|
return;
|
|
|
}
|
|
|
if (where.toString().indexOf("SELECT") > 0) {
|
|
@@ -360,16 +371,8 @@ public class TenantLineInnerInterceptor extends JsqlParserSupport implements Inn
|
|
|
/**
|
|
|
* 处理子查询等
|
|
|
*/
|
|
|
- protected void processFromItem(FromItem fromItem) {
|
|
|
- if (fromItem instanceof SubJoin) {
|
|
|
- SubJoin subJoin = (SubJoin) fromItem;
|
|
|
- if (subJoin.getJoinList() != null) {
|
|
|
- processJoins(subJoin.getJoinList());
|
|
|
- }
|
|
|
- if (subJoin.getLeft() != null) {
|
|
|
- processFromItem(subJoin.getLeft());
|
|
|
- }
|
|
|
- } else if (fromItem instanceof SubSelect) {
|
|
|
+ protected void processOtherFromItem(FromItem fromItem) {
|
|
|
+ if (fromItem instanceof SubSelect) {
|
|
|
SubSelect subSelect = (SubSelect) fromItem;
|
|
|
if (subSelect.getSelectBody() != null) {
|
|
|
processSelectBody(subSelect.getSelectBody());
|
|
@@ -387,104 +390,118 @@ public class TenantLineInnerInterceptor extends JsqlParserSupport implements Inn
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 处理 sub join
|
|
|
+ *
|
|
|
+ * @param subJoin subJoin
|
|
|
+ * @return Table subJoin 中的主表
|
|
|
+ */
|
|
|
+ private Table processSubJoin(SubJoin subJoin) {
|
|
|
+ Table mainTable = null;
|
|
|
+ if (subJoin.getJoinList() != null) {
|
|
|
+ mainTable = processFromItem(subJoin.getLeft());
|
|
|
+ mainTable = processJoins(mainTable, subJoin.getJoinList());
|
|
|
+ }
|
|
|
+ return mainTable;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 处理 joins
|
|
|
*
|
|
|
- * @param joins join 集合
|
|
|
+ * @param fromTable 可以为 null
|
|
|
+ * @param joins join 集合
|
|
|
* @return List<Table> 右连接查询的 Table 列表
|
|
|
*/
|
|
|
- private List<Table> processJoins(List<Join> joins) {
|
|
|
-
|
|
|
- List<Table> rightJointTables = new ArrayList<>();
|
|
|
+ private Table processJoins(Table fromTable, List<Join> joins) {
|
|
|
+ // join 表达式中最终的主表
|
|
|
+ Table mainTable = fromTable;
|
|
|
+ // 当前 join 的左表
|
|
|
+ Table leftTable = fromTable;
|
|
|
|
|
|
//对于 on 表达式写在最后的 join,需要记录下前面多个 on 的表名
|
|
|
- Deque<Table> tables = new LinkedList<>();
|
|
|
+ Deque<List<Table>> onTableDeque = new LinkedList<>();
|
|
|
for (Join join : joins) {
|
|
|
+ List<Table> onTables = null;
|
|
|
// 处理 on 表达式
|
|
|
- FromItem fromItem = join.getRightItem();
|
|
|
- if (fromItem instanceof Table) {
|
|
|
- Table fromTable = (Table) fromItem;
|
|
|
+ FromItem joinItem = join.getRightItem();
|
|
|
+
|
|
|
+ // 获取当前 join 的表,subJoint 可以看作是一张表
|
|
|
+ Table joinTable = null;
|
|
|
+ if (joinItem instanceof Table) {
|
|
|
+ joinTable = (Table) joinItem;
|
|
|
+ } else if (joinItem instanceof SubJoin) {
|
|
|
+ joinTable = processSubJoin((SubJoin) joinItem);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (joinTable != null) {
|
|
|
// 获取 join 尾缀的 on 表达式列表
|
|
|
Collection<Expression> originOnExpressions = join.getOnExpressions();
|
|
|
|
|
|
// 当前表是否忽略
|
|
|
- boolean needIgnore = tenantLineHandler.ignoreTable(fromTable.getName());
|
|
|
+ boolean joinTableNeedIgnore = tenantLineHandler.ignoreTable(joinTable.getName());
|
|
|
+
|
|
|
// 如果不要忽略,且是右连接,则记录下当前表
|
|
|
- if (!needIgnore && join.isRight()) {
|
|
|
- rightJointTables.add(fromTable);
|
|
|
+ if (join.isRight()) {
|
|
|
+ mainTable = joinTableNeedIgnore ? null : joinTable;
|
|
|
+ if (leftTable != null) {
|
|
|
+ onTables = Collections.singletonList(leftTable);
|
|
|
+ }
|
|
|
+ } else if (join.isLeft()) {
|
|
|
+ if (!joinTableNeedIgnore) {
|
|
|
+ onTables = Collections.singletonList(joinTable);
|
|
|
+ }
|
|
|
+ } else if (join.isInner()) {
|
|
|
+ if (mainTable == null) {
|
|
|
+ onTables = Collections.singletonList(joinTable);
|
|
|
+ } else {
|
|
|
+ onTables = Arrays.asList(mainTable, joinTable);
|
|
|
+ }
|
|
|
+ mainTable = null;
|
|
|
}
|
|
|
|
|
|
// 正常 join on 表达式只有一个,立刻处理
|
|
|
- if (originOnExpressions.size() == 1) {
|
|
|
- processJoin(join);
|
|
|
+ if (originOnExpressions.size() == 1 && onTables != null) {
|
|
|
+ List<Expression> onExpressions = new LinkedList<>();
|
|
|
+ onExpressions.add(builderExpression(originOnExpressions.iterator().next(), onTables));
|
|
|
+ join.setOnExpressions(onExpressions);
|
|
|
+ leftTable = joinTable;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
// 表名压栈,忽略的表压入 null,以便后续不处理
|
|
|
- tables.push(needIgnore ? null : fromTable);
|
|
|
+ onTableDeque.push(onTables);
|
|
|
// 尾缀多个 on 表达式的时候统一处理
|
|
|
if (originOnExpressions.size() > 1) {
|
|
|
Collection<Expression> onExpressions = new LinkedList<>();
|
|
|
for (Expression originOnExpression : originOnExpressions) {
|
|
|
- Table currentTable = tables.poll();
|
|
|
- if (currentTable == null) {
|
|
|
+ List<Table> currentTableList = onTableDeque.poll();
|
|
|
+ if (CollectionUtils.isEmpty(currentTableList)) {
|
|
|
onExpressions.add(originOnExpression);
|
|
|
} else {
|
|
|
- onExpressions.add(builderExpression(originOnExpression, currentTable));
|
|
|
+ onExpressions.add(builderExpression(originOnExpression, currentTableList));
|
|
|
}
|
|
|
}
|
|
|
join.setOnExpressions(onExpressions);
|
|
|
}
|
|
|
+ leftTable = joinTable;
|
|
|
} else {
|
|
|
- // 处理右边连接的子表达式
|
|
|
- processFromItem(fromItem);
|
|
|
+ processOtherFromItem(joinItem);
|
|
|
+ leftTable = null;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return rightJointTables;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理联接语句
|
|
|
- */
|
|
|
- protected void processJoin(Join join) {
|
|
|
- if (join.getRightItem() instanceof Table) {
|
|
|
- Table fromTable = (Table) join.getRightItem();
|
|
|
- if (tenantLineHandler.ignoreTable(fromTable.getName())) {
|
|
|
- // 过滤退出执行
|
|
|
- return;
|
|
|
- }
|
|
|
- // 走到这里说明 on 表达式肯定只有一个
|
|
|
- Collection<Expression> originOnExpressions = join.getOnExpressions();
|
|
|
- List<Expression> onExpressions = new LinkedList<>();
|
|
|
- onExpressions.add(builderExpression(originOnExpressions.iterator().next(), fromTable));
|
|
|
- join.setOnExpressions(onExpressions);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- /**
|
|
|
- * 处理条件
|
|
|
- */
|
|
|
- protected Expression builderExpression(Expression currentExpression, Table table) {
|
|
|
- return builderExpression(currentExpression, table, new ArrayList<>());
|
|
|
+ return mainTable;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 处理条件
|
|
|
*/
|
|
|
- protected Expression builderExpression(Expression currentExpression, Table table, List<Table> rightJointTables) {
|
|
|
- // 没有表需要处理直接返回
|
|
|
- if(table == null && CollectionUtils.isEmpty(rightJointTables)){
|
|
|
- return currentExpression;
|
|
|
- }
|
|
|
-
|
|
|
- // 当前需要处理的表
|
|
|
- List<Table> tables = new ArrayList<>();
|
|
|
- if(table != null){
|
|
|
- tables.add(table);
|
|
|
+ protected Expression builderExpression(Expression currentExpression, List<Table> tables) {
|
|
|
+ // 没有表需要处理直接返回
|
|
|
+ if (CollectionUtils.isEmpty(tables)) {
|
|
|
+ return currentExpression;
|
|
|
}
|
|
|
- tables.addAll(rightJointTables);
|
|
|
-
|
|
|
// 租户
|
|
|
Expression tenantId = tenantLineHandler.getTenantId();
|
|
|
// 构造每张表的条件
|
|
@@ -494,7 +511,7 @@ public class TenantLineInnerInterceptor extends JsqlParserSupport implements Inn
|
|
|
// 注入的表达式
|
|
|
Expression injectExpression = equalsTos.get(0);
|
|
|
// 如果有多表,则用 and 连接
|
|
|
- if(equalsTos.size() > 1){
|
|
|
+ if (equalsTos.size() > 1) {
|
|
|
for (int i = 1; i < equalsTos.size(); i++) {
|
|
|
injectExpression = new AndExpression(injectExpression, equalsTos.get(i));
|
|
|
}
|