更新 'pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeInnerInterceptor.java'

这样修改之后sql会走索引,数据量大的时候不至于查询超时
This commit is contained in:
202312111133 committed 2026-03-05 16:17:32 +08:00
1 parent b9268e4393
commit 173bc6853d
1 file changed
+137 -10
@@ -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<String> where = splitSqlByWhere(originalSql);
// 获取表名
String tableName = getTableName(originalSql);
List<Long> 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<String> 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;
}
}
}