From 173bc6853d13b910c4ba06d072af85368a5cac05 Mon Sep 17 00:00:00 2001 From: 202312111133 Date: Thu, 5 Mar 2026 16:17:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20'pigx-common/pigx-common-d?= =?UTF-8?q?ata/src/main/java/com/pig4cloud/pigx/common/data/datascope/Data?= =?UTF-8?q?ScopeInnerInterceptor.java'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 这样修改之后sql会走索引,数据量大的时候不至于查询超时 --- .../datascope/DataScopeInnerInterceptor.java | 147 ++++++++++++++++-- 1 file changed, 137 insertions(+), 10 deletions(-) diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInnerInterceptor.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInnerInterceptor.java index 74f2e8d3e..62f61f311 100644 --- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInnerInterceptor.java +++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInnerInterceptor.java @@ -5,19 +5,29 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.PluginUtils; import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.Statement; +import net.sf.jsqlparser.statement.select.FromItem; +import net.sf.jsqlparser.statement.select.PlainSelect; +import net.sf.jsqlparser.statement.select.Select; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; +import java.util.Collections; import java.util.List; import java.util.Map; /** - * @author lengleng + * @author legal * @date 2020/11/29 */ +@Slf4j public class DataScopeInnerInterceptor implements DataScopeInterceptor { @Setter @@ -52,13 +62,22 @@ public class DataScopeInnerInterceptor implements DataScopeInterceptor { mpBs.sql(String.format("SELECT %s FROM (%s) temp_data_scope", dataScope.getFunc().getType(), originalSql)); return; } + // 分割sql语句 + List where = splitSqlByWhere(originalSql); + // 获取表名 + String tableName = getTableName(originalSql); List deptIds = dataScope.getDeptList(); // 1.无数据权限限制,则直接返回 0 条数据 if (CollUtil.isEmpty(deptIds) && StrUtil.isBlank(dataScope.getUsername())) { - originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE 1 = 2", - dataScope.getFunc().getType(), originalSql); + if (CollUtil.isNotEmpty(where) && where.size() > 1) { + originalSql = String.format("%s WHERE 1 = 2 AND %s", where.get(0), where.get(1)); + } else { + originalSql = String.format("%s WHERE 1 = 2", where.get(0)); + } + /*originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE 1 = 2", + dataScope.getFunc().getType(), originalSql);*/ } // 2.如果为本人权限 + 部门权限控制 else if (StrUtil.isNotBlank(dataScope.getUsername()) && CollUtil.isNotEmpty(deptIds)) { @@ -66,26 +85,134 @@ public class DataScopeInnerInterceptor implements DataScopeInterceptor { // 使用配置的组合模式(AND/OR),默认OR保持向后兼容 String logicKeyword = dataScope.getLogicMode() != null ? dataScope.getLogicMode().getKeyword() : DataScopeLogicEnum.OR.getKeyword(); - originalSql = String.format( + originalSql = String.format("%s WHERE %s.%s = '%s' %s %s.%s IN (%s)", + where.get(0), + tableName, + dataScope.getScopeUserName(), + dataScope.getUsername(), + logicKeyword, + tableName, + dataScope.getScopeDeptName(), + join + ); + if (CollUtil.isNotEmpty(where) && where.size() > 1) { + originalSql = originalSql + " AND " + where.get(1); + } + /*originalSql = String.format( "SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s = '%s' %s temp_data_scope.%s IN (%s)", dataScope.getFunc().getType(), originalSql, dataScope.getScopeUserName(), dataScope.getUsername(), - logicKeyword, dataScope.getScopeDeptName(), join); + logicKeyword, dataScope.getScopeDeptName(), join);*/ } // 3. 如果为本人 else if (StrUtil.isNotBlank(dataScope.getUsername())) { - originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s = '%s'", - dataScope.getFunc().getType(), originalSql, dataScope.getScopeUserName(), dataScope.getUsername()); + if (CollUtil.isNotEmpty(where) && where.size() > 1) { + originalSql = String.format("%s WHERE %s.%s = '%s' AND %s", + where.get(0), + tableName, + dataScope.getScopeUserName(), + dataScope.getUsername(), + where.get(1) + ); + } else { + originalSql = String.format("%s WHERE %s.%s = '%s'", + where.get(0), + tableName, + dataScope.getScopeUserName(), + dataScope.getUsername() + ); + } + /*originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s = '%s'", + dataScope.getFunc().getType(), originalSql, dataScope.getScopeUserName(), dataScope.getUsername());*/ } // 4.部门权限控制 else { String join = CollectionUtil.join(deptIds, ","); - originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s IN (%s)", - dataScope.getFunc().getType(), originalSql, dataScope.getScopeDeptName(), join); + if (CollUtil.isNotEmpty(where) && where.size() > 1) { + originalSql = String.format("%s WHERE %s.%s IN (%s) AND %s", + where.get(0), + tableName, + dataScope.getScopeDeptName(), + join, + where.get(1) + ); + } else { + originalSql = String.format("%s WHERE %s.%s IN (%s)", + where.get(0), + tableName, + dataScope.getScopeDeptName(), + join + ); + } + /*originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s IN (%s)", + dataScope.getFunc().getType(), originalSql, dataScope.getScopeDeptName(), join);*/ } mpBs.sql(originalSql); } + /** + * 获取表名(优先取别名,其次取原表名) + */ + private static String getTableName(String originalSql) { + if (StrUtil.isBlank(originalSql)) { + return ""; + } + try { + Statement statement = CCJSqlParserUtil.parse(originalSql); + if (!(statement instanceof Select selectStatement)) { + return ""; + } + + // 增加 PlainSelect 类型判断,避免 UNION 等复杂语句强转异常 + if (!(selectStatement.getSelectBody() instanceof PlainSelect plainSelect)) { + return ""; + } + + FromItem fromItem = plainSelect.getFromItem(); + if (fromItem == null) { + return ""; + } + + // 优先使用别名 + if (fromItem.getAlias() != null) { + return fromItem.getAlias().getName(); + } + + // 其次使用原表名 + if (fromItem instanceof Table table) { + return table.getName(); + } + + } catch (JSQLParserException e) { + log.error("JSQLParserException: {} -- sql: {}", e.getMessage(), originalSql); + } + return ""; + } + + /** + * 分割SQL by WHERE + * @return 分割结果,失败返回空集合 + */ + private static List splitSqlByWhere(String sql) { + if (StrUtil.isBlank(sql)) { + return Collections.emptyList(); + } + try { + // 统一转大写匹配,避免遗漏大小写混合情况(如 Where / wHere) + String upperSql = sql.toUpperCase(); + int index = upperSql.indexOf(" WHERE "); + if (index != -1) { + return List.of( + sql.substring(0, index), + sql.substring(index + " WHERE ".length()) + ); + } + } catch (Exception e) { + log.error("分割SQL异常:{}--:{}", e, sql); + } + return Collections.emptyList(); + } + /** * 查找参数是否包括DataScope对象 * @@ -105,4 +232,4 @@ public class DataScopeInnerInterceptor implements DataScopeInterceptor { return null; } -} +} \ No newline at end of file