tables = processSubJoin((SubJoin) fromItem);
- mainTables.addAll(tables);
- } else {
- // 处理下 fromItem
- processOtherFromItem(fromItem);
- }
- return mainTables;
- }
-
- /**
- * 处理where条件内的子查询
- *
- * 支持如下:
- * 1. in
- * 2. =
- * 3. >
- * 4. <
- * 5. >=
- * 6. <=
- * 7. <>
- * 8. EXISTS
- * 9. NOT EXISTS
- *
- * 前提条件:
- * 1. 子查询必须放在小括号中
- * 2. 子查询一般放在比较操作符的右边
- *
- * @param where where 条件
- */
- protected void processWhereSubSelect(Expression where) {
- if (where == null) {
- return;
- }
- if (where instanceof FromItem) {
- processOtherFromItem((FromItem) where);
- return;
- }
- if (where.toString().indexOf("SELECT") > 0) {
- // 有子查询
- if (where instanceof BinaryExpression) {
- // 比较符号 , and , or , 等等
- BinaryExpression expression = (BinaryExpression) where;
- processWhereSubSelect(expression.getLeftExpression());
- processWhereSubSelect(expression.getRightExpression());
- } else if (where instanceof InExpression) {
- // in
- InExpression expression = (InExpression) where;
- Expression inExpression = expression.getRightExpression();
- if (inExpression instanceof SubSelect) {
- processSelectBody(((SubSelect) inExpression).getSelectBody());
- }
- } else if (where instanceof ExistsExpression) {
- // exists
- ExistsExpression expression = (ExistsExpression) where;
- processWhereSubSelect(expression.getRightExpression());
- } else if (where instanceof NotExpression) {
- // not exists
- NotExpression expression = (NotExpression) where;
- processWhereSubSelect(expression.getExpression());
- } else if (where instanceof Parenthesis) {
- Parenthesis expression = (Parenthesis) where;
- processWhereSubSelect(expression.getExpression());
- }
- }
- }
-
- protected void processSelectItem(SelectItem selectItem) {
- if (selectItem instanceof SelectExpressionItem) {
- SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem;
- if (selectExpressionItem.getExpression() instanceof SubSelect) {
- processSelectBody(((SubSelect) selectExpressionItem.getExpression()).getSelectBody());
- } else if (selectExpressionItem.getExpression() instanceof Function) {
- processFunction((Function) selectExpressionItem.getExpression());
- }
- }
- }
-
- /**
- * 处理函数
- *
支持: 1. select fun(args..) 2. select fun1(fun2(args..),args..)
- *
fixed gitee pulls/141
- *
- * @param function
- */
- protected void processFunction(Function function) {
- ExpressionList parameters = function.getParameters();
- if (parameters != null) {
- parameters.getExpressions().forEach(expression -> {
- if (expression instanceof SubSelect) {
- processSelectBody(((SubSelect) expression).getSelectBody());
- } else if (expression instanceof Function) {
- processFunction((Function) expression);
- }
- });
- }
- }
-
- /**
- * 处理子查询等
- */
- protected void processOtherFromItem(FromItem fromItem) {
- // 去除括号
- while (fromItem instanceof ParenthesisFromItem) {
- fromItem = ((ParenthesisFromItem) fromItem).getFromItem();
- }
-
- if (fromItem instanceof SubSelect) {
- SubSelect subSelect = (SubSelect) fromItem;
- if (subSelect.getSelectBody() != null) {
- processSelectBody(subSelect.getSelectBody());
- }
- } else if (fromItem instanceof ValuesList) {
- logger.debug("Perform a subQuery, if you do not give us feedback");
- } else if (fromItem instanceof LateralSubSelect) {
- LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem;
- if (lateralSubSelect.getSubSelect() != null) {
- SubSelect subSelect = lateralSubSelect.getSubSelect();
- if (subSelect.getSelectBody() != null) {
- processSelectBody(subSelect.getSelectBody());
- }
- }
- }
- }
-
- /**
- * 处理 sub join
- *
- * @param subJoin subJoin
- * @return Table subJoin 中的主表
- */
- private List processSubJoin(SubJoin subJoin) {
- List mainTables = new ArrayList<>();
- if (subJoin.getJoinList() != null) {
- List list = processFromItem(subJoin.getLeft());
- mainTables.addAll(list);
- mainTables = processJoins(mainTables, subJoin.getJoinList());
- }
- return mainTables;
- }
-
- /**
- * 处理 joins
- *
- * @param mainTables 可以为 null
- * @param joins join 集合
- * @return List 右连接查询的 Table 列表
- */
- private List processJoins(List mainTables, List joins) {
- // join 表达式中最终的主表
- Table mainTable = null;
- // 当前 join 的左表
- Table leftTable = null;
-
- if (mainTables == null) {
- mainTables = new ArrayList<>();
- } else if (mainTables.size() == 1) {
- mainTable = mainTables.get(0);
- leftTable = mainTable;
- }
-
- //对于 on 表达式写在最后的 join,需要记录下前面多个 on 的表名
- Deque> onTableDeque = new LinkedList<>();
- for (Join join : joins) {
- // 处理 on 表达式
- FromItem joinItem = join.getRightItem();
-
- // 获取当前 join 的表,subJoint 可以看作是一张表
- List joinTables = null;
- if (joinItem instanceof Table) {
- joinTables = new ArrayList<>();
- joinTables.add((Table) joinItem);
- } else if (joinItem instanceof SubJoin) {
- joinTables = processSubJoin((SubJoin) joinItem);
- }
-
- if (joinTables != null) {
-
- // 如果是隐式内连接
- if (join.isSimple()) {
- mainTables.addAll(joinTables);
- continue;
- }
-
- // 当前表是否忽略
- Table joinTable = joinTables.get(0);
-
- List onTables = null;
- // 如果不要忽略,且是右连接,则记录下当前表
- if (join.isRight()) {
- mainTable = joinTable;
- if (leftTable != null) {
- onTables = Collections.singletonList(leftTable);
- }
- } else if (join.isLeft()) {
- onTables = Collections.singletonList(joinTable);
- } else if (join.isInner()) {
- if (mainTable == null) {
- onTables = Collections.singletonList(joinTable);
- } else {
- onTables = Arrays.asList(mainTable, joinTable);
- }
- mainTable = null;
- }
-
- mainTables = new ArrayList<>();
- if (mainTable != null) {
- mainTables.add(mainTable);
- }
-
- // 获取 join 尾缀的 on 表达式列表
- Collection originOnExpressions = join.getOnExpressions();
- // 正常 join on 表达式只有一个,立刻处理
- if (originOnExpressions.size() == 1 && onTables != null) {
- List onExpressions = new LinkedList<>();
- onExpressions.add(builderExpression(originOnExpressions.iterator().next(), onTables));
- join.setOnExpressions(onExpressions);
- leftTable = joinTable;
- continue;
- }
- // 表名压栈,忽略的表压入 null,以便后续不处理
- onTableDeque.push(onTables);
- // 尾缀多个 on 表达式的时候统一处理
- if (originOnExpressions.size() > 1) {
- Collection onExpressions = new LinkedList<>();
- for (Expression originOnExpression : originOnExpressions) {
- List currentTableList = onTableDeque.poll();
- if (CollectionUtils.isEmpty(currentTableList)) {
- onExpressions.add(originOnExpression);
- } else {
- onExpressions.add(builderExpression(originOnExpression, currentTableList));
- }
- }
- join.setOnExpressions(onExpressions);
- }
- leftTable = joinTable;
- } else {
- processOtherFromItem(joinItem);
- leftTable = null;
- }
- }
-
- return mainTables;
}
// ========== 和 TenantLineInnerInterceptor 存在差异的逻辑:关键,实现权限条件的拼接 ==========
- /**
- * 处理条件
- *
- * @param currentExpression 当前 where 条件
- * @param table 单个表
- */
- protected Expression builderExpression(Expression currentExpression, Table table) {
- return this.builderExpression(currentExpression, Collections.singletonList(table));
- }
-
- /**
- * 处理条件
- *
- * @param currentExpression 当前 where 条件
- * @param tables 多个表
- */
- protected Expression builderExpression(Expression currentExpression, List tables) {
- // 没有表需要处理直接返回
- if (CollectionUtils.isEmpty(tables)) {
- return currentExpression;
- }
-
- // 第一步,获得 Table 对应的数据权限条件
- Expression dataPermissionExpression = null;
- for (Table table : tables) {
- // 构建每个表的权限 Expression 条件
- Expression expression = buildDataPermissionExpression(table);
- if (expression == null) {
- continue;
- }
- // 合并到 dataPermissionExpression 中
- dataPermissionExpression = dataPermissionExpression == null ? expression
- : new AndExpression(dataPermissionExpression, expression);
- }
-
- // 第二步,合并多个 Expression 条件
- if (dataPermissionExpression == null) {
- return currentExpression;
- }
- if (currentExpression == null) {
- return dataPermissionExpression;
- }
- // ① 如果表达式为 Or,则需要 (currentExpression) AND dataPermissionExpression
- if (currentExpression instanceof OrExpression) {
- return new AndExpression(new Parenthesis(currentExpression), dataPermissionExpression);
- }
- // ② 如果表达式为 And,则直接返回 where AND dataPermissionExpression
- return new AndExpression(currentExpression, dataPermissionExpression);
+ protected Expression getUpdateOrDeleteExpression(final Table table, final Expression where, final String whereSegment) {
+ return andExpression(table, where, whereSegment);
}
/**
@@ -491,7 +146,8 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
* @param table 表
* @return Expression 过滤条件
*/
- private Expression buildDataPermissionExpression(Table table) {
+ @Override
+ public Expression buildTableExpression(Table table, Expression where, String whereSegment) {
// 生成条件
Expression allExpression = null;
for (DataPermissionRule rule : ContextHolder.getRules()) {
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java
index bc54314b4..a8ee34cca 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java
@@ -156,7 +156,8 @@ public class DeptDataPermissionRule implements DataPermissionRule {
}
// 拼接条件
return new InExpression(MyBatisUtils.buildColumn(tableName, tableAlias, columnName),
- new ExpressionList(CollectionUtils.convertList(deptIds, LongValue::new)));
+ // Parenthesis 的目的,是提供 (1,2,3) 的 () 左右括号
+ new Parenthesis(new ExpressionList<>(CollectionUtils.convertList(deptIds, LongValue::new))));
}
private Expression buildUserExpression(String tableName, Alias tableAlias, Boolean self, Long userId) {
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java
index b8cad13cf..4baa2337c 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
+import net.sf.jsqlparser.expression.Parenthesis;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
@@ -71,9 +72,9 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
@Override
public Expression getExpression(String tableName, Alias tableAlias) {
Column column = MyBatisUtils.buildColumn(tableName, tableAlias, COLUMN);
- ExpressionList values = new ExpressionList(new LongValue(10L),
+ ExpressionList values = new ExpressionList<>(new LongValue(10L),
new LongValue(20L));
- return new InExpression(column, values);
+ return new InExpression(column, new Parenthesis((values)));
}
};
@@ -262,7 +263,7 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
"right join entity2 e2 on e1.id = e2.id",
"SELECT * FROM entity e " +
"LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
- "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1 " +
+ "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e.tenant_id = 1 " +
"WHERE e2.tenant_id = 1");
assertSql("SELECT * FROM entity e " +
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
index e7767c6f1..8dca318de 100644
--- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
@@ -185,8 +185,8 @@ public interface BaseMapperX extends MPJBaseMapper {
return Db.updateBatchById(entities, size);
}
- default Boolean insertOrUpdate(T entity) {
- return Db.saveOrUpdate(entity);
+ default boolean insertOrUpdate(T entity) {
+ return Db.saveOrUpdate(entity);
}
default Boolean insertOrUpdateBatch(Collection collection) {
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/type/JsonLongSetTypeHandler.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/type/JsonLongSetTypeHandler.java
deleted file mode 100644
index 052c7232e..000000000
--- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/type/JsonLongSetTypeHandler.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package cn.iocoder.yudao.framework.mybatis.core.type;
-
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
-import com.fasterxml.jackson.core.type.TypeReference;
-
-import java.util.Set;
-
-/**
- * 参考 {@link com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler} 实现
- * 在我们将字符串反序列化为 Set 并且泛型为 Long 时,如果每个元素的数值太小,会被处理成 Integer 类型,导致可能存在隐性的 BUG。
- *
- * 例如说哦,SysUserDO 的 postIds 属性
- *
- * @author 芋道源码
- */
-public class JsonLongSetTypeHandler extends AbstractJsonTypeHandler