移除sqlparse代码改调minidao方法、升级fastjson版本号到2.0.57

pull/8257/head^2
JEECG 2025-05-07 13:37:54 +08:00
parent 590d73dfe3
commit 94bff11eb1
6 changed files with 578 additions and 556 deletions

View File

@ -314,5 +314,10 @@
<groupId>org.jeecgframework.boot</groupId> <groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-starter-chatgpt</artifactId> <artifactId>jeecg-boot-starter-chatgpt</artifactId>
</dependency> </dependency>
<!-- minidao -->
<dependency>
<groupId>org.jeecgframework</groupId>
<artifactId>minidao-spring-boot-starter</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,255 +1,255 @@
package org.jeecg.common.util.sqlparse; //package org.jeecg.common.util.sqlparse;
//
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException; //import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.*; //import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.parser.CCJSqlParserManager; //import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.schema.Column; //import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table; //import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement; //import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.*; //import net.sf.jsqlparser.statement.select.*;
import org.jeecg.common.exception.JeecgBootException; //import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.sqlparse.vo.SelectSqlInfo; //import org.jeecg.common.util.sqlparse.vo.SelectSqlInfo;
//
import java.io.StringReader; //import java.io.StringReader;
import java.util.ArrayList; //import java.util.ArrayList;
import java.util.HashMap; //import java.util.HashMap;
import java.util.List; //import java.util.List;
import java.util.Map; //import java.util.Map;
//
/** ///**
* // * 解析所有表名和字段的类
*/ // */
@Slf4j //@Slf4j
public class JSqlParserAllTableManager { //public class JSqlParserAllTableManager {
//
private final String sql; // private final String sql;
private final Map<String, SelectSqlInfo> allTableMap = new HashMap<>(); // private final Map<String, SelectSqlInfo> allTableMap = new HashMap<>();
/** // /**
* // * 别名对应实际表名
*/ // */
private final Map<String, String> tableAliasMap = new HashMap<>(); // private final Map<String, String> tableAliasMap = new HashMap<>();
//
/** // /**
* sql // * 解析后的sql
*/ // */
private String parsedSql = null; // private String parsedSql = null;
//
JSqlParserAllTableManager(String selectSql) { // JSqlParserAllTableManager(String selectSql) {
this.sql = selectSql; // this.sql = selectSql;
} // }
//
/** // /**
* // * 开始解析
* // *
* @return // * @return
* @throws JSQLParserException // * @throws JSQLParserException
*/ // */
public Map<String, SelectSqlInfo> parse() throws JSQLParserException { // public Map<String, SelectSqlInfo> parse() throws JSQLParserException {
// 1. 创建解析器 // // 1. 创建解析器
CCJSqlParserManager mgr = new CCJSqlParserManager(); // CCJSqlParserManager mgr = new CCJSqlParserManager();
// 2. 使用解析器解析sql生成具有层次结构的java类 // // 2. 使用解析器解析sql生成具有层次结构的java类
Statement stmt = mgr.parse(new StringReader(this.sql)); // Statement stmt = mgr.parse(new StringReader(this.sql));
if (stmt instanceof Select) { // if (stmt instanceof Select) {
Select selectStatement = (Select) stmt; // Select selectStatement = (Select) stmt;
SelectBody selectBody = selectStatement.getSelectBody(); // SelectBody selectBody = selectStatement.getSelectBody();
this.parsedSql = selectBody.toString(); // this.parsedSql = selectBody.toString();
// 3. 解析select查询sql的信息 // // 3. 解析select查询sql的信息
if (selectBody instanceof PlainSelect) { // if (selectBody instanceof PlainSelect) {
PlainSelect plainSelect = (PlainSelect) selectBody; // PlainSelect plainSelect = (PlainSelect) selectBody;
// 4. 合并 fromItems // // 4. 合并 fromItems
List<FromItem> fromItems = new ArrayList<>(); // List<FromItem> fromItems = new ArrayList<>();
fromItems.add(plainSelect.getFromItem()); // fromItems.add(plainSelect.getFromItem());
// 4.1 处理join的表 // // 4.1 处理join的表
List<Join> joins = plainSelect.getJoins(); // List<Join> joins = plainSelect.getJoins();
if (joins != null) { // if (joins != null) {
joins.forEach(join -> fromItems.add(join.getRightItem())); // joins.forEach(join -> fromItems.add(join.getRightItem()));
} // }
// 5. 处理 fromItems // // 5. 处理 fromItems
for (FromItem fromItem : fromItems) { // for (FromItem fromItem : fromItems) {
// 5.1 通过表名的方式from // // 5.1 通过表名的方式from
if (fromItem instanceof Table) { // if (fromItem instanceof Table) {
this.addSqlInfoByTable((Table) fromItem); // this.addSqlInfoByTable((Table) fromItem);
} // }
// 5.2 通过子查询的方式from // // 5.2 通过子查询的方式from
else if (fromItem instanceof SubSelect) { // else if (fromItem instanceof SubSelect) {
this.handleSubSelect((SubSelect) fromItem); // this.handleSubSelect((SubSelect) fromItem);
} // }
} // }
// 6. 解析 selectFields // // 6. 解析 selectFields
List<SelectItem> selectItems = plainSelect.getSelectItems(); // List<SelectItem> selectItems = plainSelect.getSelectItems();
for (SelectItem selectItem : selectItems) { // for (SelectItem selectItem : selectItems) {
// 6.1 查询的是全部字段 // // 6.1 查询的是全部字段
if (selectItem instanceof AllColumns) { // if (selectItem instanceof AllColumns) {
// 当 selectItem 为 AllColumns 时fromItem 必定为 Table // // 当 selectItem 为 AllColumns 时fromItem 必定为 Table
String tableName = plainSelect.getFromItem(Table.class).getName(); // String tableName = plainSelect.getFromItem(Table.class).getName();
// 此处必定不为空,因为在解析 fromItem 时,已经将表名添加到 allTableMap 中 // // 此处必定不为空,因为在解析 fromItem 时,已经将表名添加到 allTableMap 中
SelectSqlInfo sqlInfo = this.allTableMap.get(tableName); // SelectSqlInfo sqlInfo = this.allTableMap.get(tableName);
assert sqlInfo != null; // assert sqlInfo != null;
// 设置为查询全部字段 // // 设置为查询全部字段
sqlInfo.setSelectAll(true); // sqlInfo.setSelectAll(true);
sqlInfo.setSelectFields(null); // sqlInfo.setSelectFields(null);
sqlInfo.setRealSelectFields(null); // sqlInfo.setRealSelectFields(null);
} // }
// 6.2 查询的是带表别名( u.* )的全部字段 // // 6.2 查询的是带表别名( u.* )的全部字段
else if (selectItem instanceof AllTableColumns) { // else if (selectItem instanceof AllTableColumns) {
AllTableColumns allTableColumns = (AllTableColumns) selectItem; // AllTableColumns allTableColumns = (AllTableColumns) selectItem;
String aliasName = allTableColumns.getTable().getName(); // String aliasName = allTableColumns.getTable().getName();
// 通过别名获取表名 // // 通过别名获取表名
String tableName = this.tableAliasMap.get(aliasName); // String tableName = this.tableAliasMap.get(aliasName);
if (tableName == null) { // if (tableName == null) {
tableName = aliasName; // tableName = aliasName;
} // }
SelectSqlInfo sqlInfo = this.allTableMap.get(tableName); // SelectSqlInfo sqlInfo = this.allTableMap.get(tableName);
// 如果此处为空,则说明该字段是通过子查询获取的,所以可以不处理,只有实际表才需要处理 // // 如果此处为空,则说明该字段是通过子查询获取的,所以可以不处理,只有实际表才需要处理
if (sqlInfo != null) { // if (sqlInfo != null) {
// 设置为查询全部字段 // // 设置为查询全部字段
sqlInfo.setSelectAll(true); // sqlInfo.setSelectAll(true);
sqlInfo.setSelectFields(null); // sqlInfo.setSelectFields(null);
sqlInfo.setRealSelectFields(null); // sqlInfo.setRealSelectFields(null);
} // }
} // }
// 6.3 各种字段表达式处理 // // 6.3 各种字段表达式处理
else if (selectItem instanceof SelectExpressionItem) { // else if (selectItem instanceof SelectExpressionItem) {
SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem; // SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem;
Expression expression = selectExpressionItem.getExpression(); // Expression expression = selectExpressionItem.getExpression();
Alias alias = selectExpressionItem.getAlias(); // Alias alias = selectExpressionItem.getAlias();
this.handleExpression(expression, alias, plainSelect.getFromItem()); // this.handleExpression(expression, alias, plainSelect.getFromItem());
} // }
} // }
} else { // } else {
log.warn("暂时尚未处理该类型的 SelectBody: {}", selectBody.getClass().getName()); // log.warn("暂时尚未处理该类型的 SelectBody: {}", selectBody.getClass().getName());
throw new JeecgBootException("暂时尚未处理该类型的 SelectBody"); // throw new JeecgBootException("暂时尚未处理该类型的 SelectBody");
} // }
} else { // } else {
// 非 select 查询sql不做处理 // // 非 select 查询sql不做处理
throw new JeecgBootException("非 select 查询sql不做处理"); // throw new JeecgBootException("非 select 查询sql不做处理");
} // }
return this.allTableMap; // return this.allTableMap;
} // }
//
/** // /**
* // * 处理子查询
* // *
* @param subSelect // * @param subSelect
*/ // */
private void handleSubSelect(SubSelect subSelect) { // private void handleSubSelect(SubSelect subSelect) {
try { // try {
String subSelectSql = subSelect.getSelectBody().toString(); // String subSelectSql = subSelect.getSelectBody().toString();
// 递归调用解析 // // 递归调用解析
Map<String, SelectSqlInfo> map = JSqlParserUtils.parseAllSelectTable(subSelectSql); // Map<String, SelectSqlInfo> map = JSqlParserUtils.parseAllSelectTable(subSelectSql);
if (map != null) { // if (map != null) {
this.assignMap(map); // this.assignMap(map);
} // }
} catch (Exception e) { // } catch (Exception e) {
log.error("解析子查询出错", e); // log.error("解析子查询出错", e);
} // }
} // }
//
/** // /**
* // * 处理查询字段表达式
* // *
* @param expression // * @param expression
*/ // */
private void handleExpression(Expression expression, Alias alias, FromItem fromItem) { // private void handleExpression(Expression expression, Alias alias, FromItem fromItem) {
// 处理函数式字段 CONCAT(name,'(',age,')') // // 处理函数式字段 CONCAT(name,'(',age,')')
if (expression instanceof Function) { // if (expression instanceof Function) {
Function functionExp = (Function) expression; // Function functionExp = (Function) expression;
List<Expression> expressions = functionExp.getParameters().getExpressions(); // List<Expression> expressions = functionExp.getParameters().getExpressions();
for (Expression expItem : expressions) { // for (Expression expItem : expressions) {
this.handleExpression(expItem, null, fromItem); // this.handleExpression(expItem, null, fromItem);
} // }
return; // return;
} // }
// 处理字段上的子查询 // // 处理字段上的子查询
if (expression instanceof SubSelect) { // if (expression instanceof SubSelect) {
this.handleSubSelect((SubSelect) expression); // this.handleSubSelect((SubSelect) expression);
return; // return;
} // }
// 不处理字面量 // // 不处理字面量
if (expression instanceof StringValue || // if (expression instanceof StringValue ||
expression instanceof NullValue || // expression instanceof NullValue ||
expression instanceof LongValue || // expression instanceof LongValue ||
expression instanceof DoubleValue || // expression instanceof DoubleValue ||
expression instanceof HexValue || // expression instanceof HexValue ||
expression instanceof DateValue || // expression instanceof DateValue ||
expression instanceof TimestampValue || // expression instanceof TimestampValue ||
expression instanceof TimeValue // expression instanceof TimeValue
) { // ) {
return; // return;
} // }
//
// 处理字段 // // 处理字段
if (expression instanceof Column) { // if (expression instanceof Column) {
Column column = (Column) expression; // Column column = (Column) expression;
// 查询字段名 // // 查询字段名
String fieldName = column.getColumnName(); // String fieldName = column.getColumnName();
String aliasName = fieldName; // String aliasName = fieldName;
if (alias != null) { // if (alias != null) {
aliasName = alias.getName(); // aliasName = alias.getName();
} // }
String tableName; // String tableName;
if (column.getTable() != null) { // if (column.getTable() != null) {
// 通过列的表名获取 sqlInfo // // 通过列的表名获取 sqlInfo
// 例如 user.name这里的 tableName 就是 user // // 例如 user.name这里的 tableName 就是 user
tableName = column.getTable().getName(); // tableName = column.getTable().getName();
// 有可能是别名,需要转换为真实表名 // // 有可能是别名,需要转换为真实表名
if (this.tableAliasMap.get(tableName) != null) { // if (this.tableAliasMap.get(tableName) != null) {
tableName = this.tableAliasMap.get(tableName); // tableName = this.tableAliasMap.get(tableName);
} // }
} else { // } else {
// 当column的table为空时说明是 fromItem 中的字段 // // 当column的table为空时说明是 fromItem 中的字段
tableName = ((Table) fromItem).getName(); // tableName = ((Table) fromItem).getName();
} // }
SelectSqlInfo $sqlInfo = this.allTableMap.get(tableName); // SelectSqlInfo $sqlInfo = this.allTableMap.get(tableName);
if ($sqlInfo != null) { // if ($sqlInfo != null) {
$sqlInfo.addSelectField(aliasName, fieldName); // $sqlInfo.addSelectField(aliasName, fieldName);
} else { // } else {
log.warn("发生意外情况,未找到表名为 {} 的 SelectSqlInfo", tableName); // log.warn("发生意外情况,未找到表名为 {} 的 SelectSqlInfo", tableName);
} // }
} // }
} // }
//
/** // /**
* sqlInfo // * 根据表名添加sqlInfo
* // *
* @param table // * @param table
*/ // */
private void addSqlInfoByTable(Table table) { // private void addSqlInfoByTable(Table table) {
String tableName = table.getName(); // String tableName = table.getName();
// 解析 aliasName // // 解析 aliasName
if (table.getAlias() != null) { // if (table.getAlias() != null) {
this.tableAliasMap.put(table.getAlias().getName(), tableName); // this.tableAliasMap.put(table.getAlias().getName(), tableName);
} // }
SelectSqlInfo sqlInfo = new SelectSqlInfo(this.parsedSql); // SelectSqlInfo sqlInfo = new SelectSqlInfo(this.parsedSql);
sqlInfo.setFromTableName(table.getName()); // sqlInfo.setFromTableName(table.getName());
this.allTableMap.put(sqlInfo.getFromTableName(), sqlInfo); // this.allTableMap.put(sqlInfo.getFromTableName(), sqlInfo);
} // }
//
/** // /**
* map // * 合并map
* // *
* @param source // * @param source
*/ // */
private void assignMap(Map<String, SelectSqlInfo> source) { // private void assignMap(Map<String, SelectSqlInfo> source) {
for (Map.Entry<String, SelectSqlInfo> entry : source.entrySet()) { // for (Map.Entry<String, SelectSqlInfo> entry : source.entrySet()) {
SelectSqlInfo sqlInfo = this.allTableMap.get(entry.getKey()); // SelectSqlInfo sqlInfo = this.allTableMap.get(entry.getKey());
if (sqlInfo == null) { // if (sqlInfo == null) {
this.allTableMap.put(entry.getKey(), entry.getValue()); // this.allTableMap.put(entry.getKey(), entry.getValue());
} else { // } else {
// 合并 // // 合并
if (sqlInfo.getSelectFields() == null) { // if (sqlInfo.getSelectFields() == null) {
sqlInfo.setSelectFields(entry.getValue().getSelectFields()); // sqlInfo.setSelectFields(entry.getValue().getSelectFields());
} else { // } else {
sqlInfo.getSelectFields().addAll(entry.getValue().getSelectFields()); // sqlInfo.getSelectFields().addAll(entry.getValue().getSelectFields());
} // }
if (sqlInfo.getRealSelectFields() == null) { // if (sqlInfo.getRealSelectFields() == null) {
sqlInfo.setRealSelectFields(entry.getValue().getRealSelectFields()); // sqlInfo.setRealSelectFields(entry.getValue().getRealSelectFields());
} else { // } else {
sqlInfo.getRealSelectFields().addAll(entry.getValue().getRealSelectFields()); // sqlInfo.getRealSelectFields().addAll(entry.getValue().getRealSelectFields());
} // }
} // }
} // }
} // }
//
} //}

View File

@ -1,190 +1,190 @@
package org.jeecg.common.util.sqlparse; //package org.jeecg.common.util.sqlparse;
//
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException; //import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.*; //import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.parser.CCJSqlParserManager; //import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.schema.Column; //import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table; //import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement; //import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.*; //import net.sf.jsqlparser.statement.select.*;
import org.jeecg.common.exception.JeecgBootException; //import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.oConvertUtils; //import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.util.sqlparse.vo.SelectSqlInfo; //import org.jeecg.common.util.sqlparse.vo.SelectSqlInfo;
//
import java.io.StringReader; //import java.io.StringReader;
import java.util.List; //import java.util.List;
import java.util.Map; //import java.util.Map;
//
@Slf4j //@Slf4j
public class JSqlParserUtils { //public class JSqlParserUtils {
//
/** // /**
* selectsql // * 解析 查询selectsql的信息
* map // * 此方法会展开所有子查询到一个map里
* key // * key只存真实的表名如果查询的没有真实的表名则会被忽略。
* value // * value只存真实的字段名如果查询的没有真实的字段名则会被忽略。
* <p> // * <p>
* SELECT a.*,d.age,(SELECT count(1) FROM sys_depart) AS count FROM (SELECT username AS foo, realname FROM sys_user) a, demo d // * 例如SELECT a.*,d.age,(SELECT count(1) FROM sys_depart) AS count FROM (SELECT username AS foo, realname FROM sys_user) a, demo d
* {sys_user=[username, realname], demo=[age], sys_depart=[]} // * 解析后的结果为:{sys_user=[username, realname], demo=[age], sys_depart=[]}
* // *
* @param selectSql // * @param selectSql
* @return // * @return
*/ // */
public static Map<String, SelectSqlInfo> parseAllSelectTable(String selectSql) throws JSQLParserException { // public static Map<String, SelectSqlInfo> parseAllSelectTable(String selectSql) throws JSQLParserException {
if (oConvertUtils.isEmpty(selectSql)) { // if (oConvertUtils.isEmpty(selectSql)) {
return null; // return null;
} // }
// log.info("解析查询Sql{}", selectSql); // // log.info("解析查询Sql{}", selectSql);
JSqlParserAllTableManager allTableManager = new JSqlParserAllTableManager(selectSql); // JSqlParserAllTableManager allTableManager = new JSqlParserAllTableManager(selectSql);
return allTableManager.parse(); // return allTableManager.parse();
} // }
//
/** // /**
* selectsql // * 解析 查询selectsql的信息子查询嵌套
* // *
* @param selectSql // * @param selectSql
* @return // * @return
*/ // */
public static SelectSqlInfo parseSelectSqlInfo(String selectSql) throws JSQLParserException { // public static SelectSqlInfo parseSelectSqlInfo(String selectSql) throws JSQLParserException {
if (oConvertUtils.isEmpty(selectSql)) { // if (oConvertUtils.isEmpty(selectSql)) {
return null; // return null;
} // }
// log.info("解析查询Sql{}", selectSql); // // log.info("解析查询Sql{}", selectSql);
// 使用 JSqlParer 解析sql // // 使用 JSqlParer 解析sql
// 1、创建解析器 // // 1、创建解析器
CCJSqlParserManager mgr = new CCJSqlParserManager(); // CCJSqlParserManager mgr = new CCJSqlParserManager();
// 2、使用解析器解析sql生成具有层次结构的java类 // // 2、使用解析器解析sql生成具有层次结构的java类
Statement stmt = mgr.parse(new StringReader(selectSql)); // Statement stmt = mgr.parse(new StringReader(selectSql));
if (stmt instanceof Select) { // if (stmt instanceof Select) {
Select selectStatement = (Select) stmt; // Select selectStatement = (Select) stmt;
// 3、解析select查询sql的信息 // // 3、解析select查询sql的信息
return JSqlParserUtils.parseBySelectBody(selectStatement.getSelectBody()); // return JSqlParserUtils.parseBySelectBody(selectStatement.getSelectBody());
} else { // } else {
// 非 select 查询sql不做处理 // // 非 select 查询sql不做处理
throw new JeecgBootException("非 select 查询sql不做处理"); // throw new JeecgBootException("非 select 查询sql不做处理");
} // }
} // }
//
/** // /**
* select sql // * 解析 select 查询sql的信息
* // *
* @param selectBody // * @param selectBody
* @return // * @return
*/ // */
private static SelectSqlInfo parseBySelectBody(SelectBody selectBody) { // private static SelectSqlInfo parseBySelectBody(SelectBody selectBody) {
// 判断是否使用了union等操作 // // 判断是否使用了union等操作
if (selectBody instanceof SetOperationList) { // if (selectBody instanceof SetOperationList) {
// 如果使用了union等操作则只解析第一个查询 // // 如果使用了union等操作则只解析第一个查询
List<SelectBody> selectBodyList = ((SetOperationList) selectBody).getSelects(); // List<SelectBody> selectBodyList = ((SetOperationList) selectBody).getSelects();
return JSqlParserUtils.parseBySelectBody(selectBodyList.get(0)); // return JSqlParserUtils.parseBySelectBody(selectBodyList.get(0));
} // }
// 简单的select查询 // // 简单的select查询
if (selectBody instanceof PlainSelect) { // if (selectBody instanceof PlainSelect) {
SelectSqlInfo sqlInfo = new SelectSqlInfo(selectBody); // SelectSqlInfo sqlInfo = new SelectSqlInfo(selectBody);
PlainSelect plainSelect = (PlainSelect) selectBody; // PlainSelect plainSelect = (PlainSelect) selectBody;
FromItem fromItem = plainSelect.getFromItem(); // FromItem fromItem = plainSelect.getFromItem();
// 解析 aliasName // // 解析 aliasName
if (fromItem.getAlias() != null) { // if (fromItem.getAlias() != null) {
sqlInfo.setFromTableAliasName(fromItem.getAlias().getName()); // sqlInfo.setFromTableAliasName(fromItem.getAlias().getName());
} // }
// 解析 表名 // // 解析 表名
if (fromItem instanceof Table) { // if (fromItem instanceof Table) {
// 通过表名的方式from // // 通过表名的方式from
Table fromTable = (Table) fromItem; // Table fromTable = (Table) fromItem;
sqlInfo.setFromTableName(fromTable.getName()); // sqlInfo.setFromTableName(fromTable.getName());
} else if (fromItem instanceof SubSelect) { // } else if (fromItem instanceof SubSelect) {
// 通过子查询的方式from // // 通过子查询的方式from
SubSelect fromSubSelect = (SubSelect) fromItem; // SubSelect fromSubSelect = (SubSelect) fromItem;
SelectSqlInfo subSqlInfo = JSqlParserUtils.parseBySelectBody(fromSubSelect.getSelectBody()); // SelectSqlInfo subSqlInfo = JSqlParserUtils.parseBySelectBody(fromSubSelect.getSelectBody());
sqlInfo.setFromSubSelect(subSqlInfo); // sqlInfo.setFromSubSelect(subSqlInfo);
} // }
// 解析 selectFields // // 解析 selectFields
List<SelectItem> selectItems = plainSelect.getSelectItems(); // List<SelectItem> selectItems = plainSelect.getSelectItems();
for (SelectItem selectItem : selectItems) { // for (SelectItem selectItem : selectItems) {
if (selectItem instanceof AllColumns || selectItem instanceof AllTableColumns) { // if (selectItem instanceof AllColumns || selectItem instanceof AllTableColumns) {
// 全部字段 // // 全部字段
sqlInfo.setSelectAll(true); // sqlInfo.setSelectAll(true);
sqlInfo.setSelectFields(null); // sqlInfo.setSelectFields(null);
sqlInfo.setRealSelectFields(null); // sqlInfo.setRealSelectFields(null);
break; // break;
} else if (selectItem instanceof SelectExpressionItem) { // } else if (selectItem instanceof SelectExpressionItem) {
// 获取单个查询字段名 // // 获取单个查询字段名
SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem; // SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem;
Expression expression = selectExpressionItem.getExpression(); // Expression expression = selectExpressionItem.getExpression();
Alias alias = selectExpressionItem.getAlias(); // Alias alias = selectExpressionItem.getAlias();
JSqlParserUtils.handleExpression(sqlInfo, expression, alias); // JSqlParserUtils.handleExpression(sqlInfo, expression, alias);
} // }
} // }
return sqlInfo; // return sqlInfo;
} else { // } else {
log.warn("暂时尚未处理该类型的 SelectBody: {}", selectBody.getClass().getName()); // log.warn("暂时尚未处理该类型的 SelectBody: {}", selectBody.getClass().getName());
throw new JeecgBootException("暂时尚未处理该类型的 SelectBody"); // throw new JeecgBootException("暂时尚未处理该类型的 SelectBody");
} // }
} // }
//
/** // /**
* // * 处理查询字段表达式
* // *
* @param sqlInfo // * @param sqlInfo
* @param expression // * @param expression
* @param alias null // * @param alias 是否有别名无传null
*/ // */
private static void handleExpression(SelectSqlInfo sqlInfo, Expression expression, Alias alias) { // private static void handleExpression(SelectSqlInfo sqlInfo, Expression expression, Alias alias) {
// 处理函数式字段 CONCAT(name,'(',age,')') // // 处理函数式字段 CONCAT(name,'(',age,')')
if (expression instanceof Function) { // if (expression instanceof Function) {
JSqlParserUtils.handleFunctionExpression((Function) expression, sqlInfo); // JSqlParserUtils.handleFunctionExpression((Function) expression, sqlInfo);
return; // return;
} // }
// 处理字段上的子查询 // // 处理字段上的子查询
if (expression instanceof SubSelect) { // if (expression instanceof SubSelect) {
SubSelect subSelect = (SubSelect) expression; // SubSelect subSelect = (SubSelect) expression;
SelectSqlInfo subSqlInfo = JSqlParserUtils.parseBySelectBody(subSelect.getSelectBody()); // SelectSqlInfo subSqlInfo = JSqlParserUtils.parseBySelectBody(subSelect.getSelectBody());
// 注:字段上的子查询,必须只查询一个字段,否则会报错,所以可以放心合并 // // 注:字段上的子查询,必须只查询一个字段,否则会报错,所以可以放心合并
sqlInfo.getSelectFields().addAll(subSqlInfo.getSelectFields()); // sqlInfo.getSelectFields().addAll(subSqlInfo.getSelectFields());
sqlInfo.getRealSelectFields().addAll(subSqlInfo.getAllRealSelectFields()); // sqlInfo.getRealSelectFields().addAll(subSqlInfo.getAllRealSelectFields());
return; // return;
} // }
// 不处理字面量 // // 不处理字面量
if (expression instanceof StringValue || // if (expression instanceof StringValue ||
expression instanceof NullValue || // expression instanceof NullValue ||
expression instanceof LongValue || // expression instanceof LongValue ||
expression instanceof DoubleValue || // expression instanceof DoubleValue ||
expression instanceof HexValue || // expression instanceof HexValue ||
expression instanceof DateValue || // expression instanceof DateValue ||
expression instanceof TimestampValue || // expression instanceof TimestampValue ||
expression instanceof TimeValue // expression instanceof TimeValue
) { // ) {
return; // return;
} // }
//
// 查询字段名 // // 查询字段名
String selectField = expression.toString(); // String selectField = expression.toString();
// 实际查询字段名 // // 实际查询字段名
String realSelectField = selectField; // String realSelectField = selectField;
// 判断是否有别名 // // 判断是否有别名
if (alias != null) { // if (alias != null) {
selectField = alias.getName(); // selectField = alias.getName();
} // }
// 获取真实字段名 // // 获取真实字段名
if (expression instanceof Column) { // if (expression instanceof Column) {
Column column = (Column) expression; // Column column = (Column) expression;
realSelectField = column.getColumnName(); // realSelectField = column.getColumnName();
} // }
sqlInfo.addSelectField(selectField, realSelectField); // sqlInfo.addSelectField(selectField, realSelectField);
} // }
//
/** // /**
* // * 处理函数式字段
* // *
* @param functionExp // * @param functionExp
* @param sqlInfo // * @param sqlInfo
*/ // */
private static void handleFunctionExpression(Function functionExp, SelectSqlInfo sqlInfo) { // private static void handleFunctionExpression(Function functionExp, SelectSqlInfo sqlInfo) {
List<Expression> expressions = functionExp.getParameters().getExpressions(); // List<Expression> expressions = functionExp.getParameters().getExpressions();
for (Expression expression : expressions) { // for (Expression expression : expressions) {
JSqlParserUtils.handleExpression(sqlInfo, expression, null); // JSqlParserUtils.handleExpression(sqlInfo, expression, null);
} // }
} // }
//
} //}

View File

@ -1,101 +1,101 @@
package org.jeecg.common.util.sqlparse.vo; //package org.jeecg.common.util.sqlparse.vo;
//
import lombok.Data; //import lombok.Data;
import net.sf.jsqlparser.statement.select.SelectBody; //import net.sf.jsqlparser.statement.select.SelectBody;
//
import java.util.HashSet; //import java.util.HashSet;
import java.util.Set; //import java.util.Set;
//
/** ///**
* select sql // * select 查询 sql 的信息
*/ // */
@Data //@Data
public class SelectSqlInfo { //public class SelectSqlInfo {
//
/** // /**
* null // * 查询的表名如果是子查询则此处为null
*/ // */
private String fromTableName; // private String fromTableName;
/** // /**
* // * 表别名
*/ // */
private String fromTableAliasName; // private String fromTableAliasName;
/** // /**
* select name from (select * from user) u // * 通过子查询获取的表信息例如select name from (select * from user) u
* null // * 如果不是子查询则为null
*/ // */
private SelectSqlInfo fromSubSelect; // private SelectSqlInfo fromSubSelect;
/** // /**
* * null // * 查询的字段集合,如果是 * 则为null如果设了别名则为别名
*/ // */
private Set<String> selectFields; // private Set<String> selectFields;
/** // /**
* * null // * 真实的查询字段集合,如果是 * 则为null如果设了别名则为原始字段名
*/ // */
private Set<String> realSelectFields; // private Set<String> realSelectFields;
/** // /**
* // * 是否是查询所有字段
*/ // */
private boolean selectAll; // private boolean selectAll;
//
/** // /**
* SQL // * 解析之后的 SQL (关键字都是大写)
*/ // */
private final String parsedSql; // private final String parsedSql;
//
public SelectSqlInfo(String parsedSql) { // public SelectSqlInfo(String parsedSql) {
this.parsedSql = parsedSql; // this.parsedSql = parsedSql;
} // }
//
public SelectSqlInfo(SelectBody selectBody) { // public SelectSqlInfo(SelectBody selectBody) {
this.parsedSql = selectBody.toString(); // this.parsedSql = selectBody.toString();
} // }
//
public void addSelectField(String selectField, String realSelectField) { // public void addSelectField(String selectField, String realSelectField) {
if (this.selectFields == null) { // if (this.selectFields == null) {
this.selectFields = new HashSet<>(); // this.selectFields = new HashSet<>();
} // }
if (this.realSelectFields == null) { // if (this.realSelectFields == null) {
this.realSelectFields = new HashSet<>(); // this.realSelectFields = new HashSet<>();
} // }
this.selectFields.add(selectField); // this.selectFields.add(selectField);
this.realSelectFields.add(realSelectField); // this.realSelectFields.add(realSelectField);
} // }
//
/** // /**
* // * 获取所有字段,包括子查询里的。
* // *
* @return // * @return
*/ // */
public Set<String> getAllRealSelectFields() { // public Set<String> getAllRealSelectFields() {
Set<String> fields = new HashSet<>(); // Set<String> fields = new HashSet<>();
// 递归获取所有字段,起个直观的方法名为: // // 递归获取所有字段,起个直观的方法名为:
this.recursiveGetAllFields(this, fields); // this.recursiveGetAllFields(this, fields);
return fields; // return fields;
} // }
//
/** // /**
* // * 递归获取所有字段
*/ // */
private void recursiveGetAllFields(SelectSqlInfo sqlInfo, Set<String> fields) { // private void recursiveGetAllFields(SelectSqlInfo sqlInfo, Set<String> fields) {
if (!sqlInfo.isSelectAll() && sqlInfo.getRealSelectFields() != null) { // if (!sqlInfo.isSelectAll() && sqlInfo.getRealSelectFields() != null) {
fields.addAll(sqlInfo.getRealSelectFields()); // fields.addAll(sqlInfo.getRealSelectFields());
} // }
if (sqlInfo.getFromSubSelect() != null) { // if (sqlInfo.getFromSubSelect() != null) {
recursiveGetAllFields(sqlInfo.getFromSubSelect(), fields); // recursiveGetAllFields(sqlInfo.getFromSubSelect(), fields);
} // }
} // }
//
@Override // @Override
public String toString() { // public String toString() {
return "SelectSqlInfo{" + // return "SelectSqlInfo{" +
"fromTableName='" + fromTableName + '\'' + // "fromTableName='" + fromTableName + '\'' +
", fromSubSelect=" + fromSubSelect + // ", fromSubSelect=" + fromSubSelect +
", aliasName='" + fromTableAliasName + '\'' + // ", aliasName='" + fromTableAliasName + '\'' +
", selectFields=" + selectFields + // ", selectFields=" + selectFields +
", realSelectFields=" + realSelectFields + // ", realSelectFields=" + realSelectFields +
", selectAll=" + selectAll + // ", selectAll=" + selectAll +
"}"; // "}";
} // }
//
} //}

View File

@ -4,14 +4,14 @@ import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.exception.JeecgSqlInjectionException; import org.jeecg.common.exception.JeecgSqlInjectionException;
import org.jeecg.common.util.oConvertUtils; import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.util.sqlparse.JSqlParserUtils;
import org.jeecg.common.util.sqlparse.vo.SelectSqlInfo;
import org.jeecg.config.JeecgBaseConfig; import org.jeecg.config.JeecgBaseConfig;
import org.jeecg.config.firewall.SqlInjection.IDictTableWhiteListHandler; import org.jeecg.config.firewall.SqlInjection.IDictTableWhiteListHandler;
import org.jeecg.config.firewall.interceptor.LowCodeModeInterceptor; import org.jeecg.config.firewall.interceptor.LowCodeModeInterceptor;
import org.jeecg.modules.system.entity.SysTableWhiteList; import org.jeecg.modules.system.entity.SysTableWhiteList;
import org.jeecg.modules.system.security.DictQueryBlackListHandler; import org.jeecg.modules.system.security.DictQueryBlackListHandler;
import org.jeecg.modules.system.service.ISysTableWhiteListService; import org.jeecg.modules.system.service.ISysTableWhiteListService;
import org.jeecgframework.minidao.sqlparser.impl.vo.SelectSqlInfo;
import org.jeecgframework.minidao.util.MiniDaoUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -65,7 +65,7 @@ public class DictTableWhiteListHandlerImpl implements IDictTableWhiteListHandler
public boolean isPassBySql(String sql) { public boolean isPassBySql(String sql) {
Map<String, SelectSqlInfo> parsedMap = null; Map<String, SelectSqlInfo> parsedMap = null;
try { try {
parsedMap = JSqlParserUtils.parseAllSelectTable(sql); parsedMap = MiniDaoUtil.parseAllSelectTable(sql);
} catch (Exception e) { } catch (Exception e) {
log.warn("校验sql语句解析报错{}", e.getMessage()); log.warn("校验sql语句解析报错{}", e.getMessage());
} }
@ -127,7 +127,7 @@ public class DictTableWhiteListHandlerImpl implements IDictTableWhiteListHandler
log.info("字典拼接的查询SQL{}", sql); log.info("字典拼接的查询SQL{}", sql);
try { try {
// 进行SQL解析 // 进行SQL解析
JSqlParserUtils.parseSelectSqlInfo(sql); MiniDaoUtil.parseSelectSqlInfo(sql);
} catch (Exception e) { } catch (Exception e) {
// 如果SQL解析失败则通过字段名和表名进行校验 // 如果SQL解析失败则通过字段名和表名进行校验
return checkWhiteList(tableName, new HashSet<>(Arrays.asList(fields))); return checkWhiteList(tableName, new HashSet<>(Arrays.asList(fields)));

View File

@ -40,7 +40,7 @@
<seata.version>1.5.2</seata.version> <seata.version>1.5.2</seata.version>
<xxl-job-core.version>2.4.1</xxl-job-core.version> <xxl-job-core.version>2.4.1</xxl-job-core.version>
<fastjson.version>2.0.56</fastjson.version> <fastjson.version>2.0.57</fastjson.version>
<aviator.version>5.2.6</aviator.version> <aviator.version>5.2.6</aviator.version>
<pegdown.version>1.6.0</pegdown.version> <pegdown.version>1.6.0</pegdown.version>
<commonmark.version>0.17.0</commonmark.version> <commonmark.version>0.17.0</commonmark.version>
@ -56,7 +56,8 @@
<dm8.version>8.1.1.49</dm8.version> <dm8.version>8.1.1.49</dm8.version>
<!-- 积木报表--> <!-- 积木报表-->
<jimureport-spring-boot-starter.version>1.9.5</jimureport-spring-boot-starter.version> <jimureport-spring-boot-starter.version>1.9.5.1</jimureport-spring-boot-starter.version>
<minidao.version>1.10.7</minidao.version>
<!-- 持久层 --> <!-- 持久层 -->
<mybatis-plus.version>3.5.3.2</mybatis-plus.version> <mybatis-plus.version>3.5.3.2</mybatis-plus.version>
<dynamic-datasource-spring-boot-starter.version>4.1.3</dynamic-datasource-spring-boot-starter.version> <dynamic-datasource-spring-boot-starter.version>4.1.3</dynamic-datasource-spring-boot-starter.version>
@ -254,7 +255,7 @@
<dependency> <dependency>
<groupId>org.jeecgframework.boot</groupId> <groupId>org.jeecgframework.boot</groupId>
<artifactId>hibernate-re</artifactId> <artifactId>hibernate-re</artifactId>
<version>3.8.0-GA</version> <version>3.8.0.1</version>
</dependency> </dependency>
<!--mongon db--> <!--mongon db-->
@ -359,7 +360,7 @@
<dependency> <dependency>
<groupId>org.jeecgframework</groupId> <groupId>org.jeecgframework</groupId>
<artifactId>weixin4j</artifactId> <artifactId>weixin4j</artifactId>
<version>2.0.2</version> <version>2.0.4</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<artifactId>commons-beanutils</artifactId> <artifactId>commons-beanutils</artifactId>
@ -383,6 +384,22 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<!-- minidao -->
<dependency>
<groupId>org.jeecgframework</groupId>
<artifactId>minidao-spring-boot-starter</artifactId>
<version>${minidao.version}</version>
<exclusions>
<exclusion>
<artifactId>druid</artifactId>
<groupId>com.alibaba</groupId>
</exclusion>
<exclusion>
<artifactId>jsqlparser</artifactId>
<groupId>com.github.jsqlparser</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 积木报表--> <!-- 积木报表-->
<dependency> <dependency>
<groupId>org.jeecgframework.jimureport</groupId> <groupId>org.jeecgframework.jimureport</groupId>
@ -418,7 +435,7 @@
<dependency> <dependency>
<groupId>org.jeecgframework.jimureport</groupId> <groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimureport-nosql-starter</artifactId> <artifactId>jimureport-nosql-starter</artifactId>
<version>${jimureport-spring-boot-starter.version}</version> <version>1.9.5.2</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>org.apache.calcite</groupId> <groupId>org.apache.calcite</groupId>
@ -430,7 +447,7 @@
<dependency> <dependency>
<groupId>org.jeecgframework.jimureport</groupId> <groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimubi-spring-boot-starter</artifactId> <artifactId>jimubi-spring-boot-starter</artifactId>
<version>1.9.4</version> <version>1.9.5</version>
</dependency> </dependency>
<!-- AI集成 --> <!-- AI集成 -->
<dependency> <dependency>