| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- package com.kingdee.eas.custom.dataconfig.utils;
- import net.sf.jsqlparser.JSQLParserException;
- import net.sf.jsqlparser.expression.Expression;
- import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
- import net.sf.jsqlparser.parser.CCJSqlParserUtil;
- import net.sf.jsqlparser.schema.Column;
- import net.sf.jsqlparser.schema.Table;
- import net.sf.jsqlparser.statement.Statement;
- import net.sf.jsqlparser.statement.select.*;
- import net.sf.jsqlparser.util.TablesNamesFinder;
- import java.util.*;
- public class NativeSqlJoinOptimizer {
- public String cleanRedundantJoins(String originalSql) throws JSQLParserException {
- // 1. 解析SQL
- Statement statement = CCJSqlParserUtil.parse(originalSql);
- Select select = (Select) statement;
- PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
- // 2. 提取所有被使用的表名(用内置工具类,更稳定)
- Set<String> usedTables = getUsedTables(plainSelect);
- System.out.println("被使用的表:" + usedTables); // 输出 [t1, t2]
- // 3. 过滤冗余JOIN
- List<Join> filteredJoins = new ArrayList<>();
- if (plainSelect.getJoins() != null) {
- for (Join join : plainSelect.getJoins()) {
- if (join.getRightItem() instanceof Table) {
- Table joinTable = (Table) join.getRightItem();
- String tableName = joinTable.getName();
- if (usedTables.contains(tableName)) {
- filteredJoins.add(join);
- }
- }
- }
- }
- // 4. 重构SQL
- plainSelect.setJoins(filteredJoins);
- String optimizedSql = plainSelect.toString();
- System.out.println("优化后的SQL:" + optimizedSql);
- return optimizedSql;
- }
- /**
- * 提取使用的表名(不依赖SelectExpressionItem)
- */
- private static Set<String> getUsedTables(PlainSelect plainSelect) {
- Set<String> usedTables = new HashSet<>();
- TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
- // 1. 提取主表(FROM)
- if (plainSelect.getFromItem() instanceof Table) {
- Table fromTable = (Table) plainSelect.getFromItem();
- usedTables.add(fromTable.getName());
- }
- // 2. 提取SELECT字段中的表(遍历Column,直接获取表名)
- for (SelectItem item : plainSelect.getSelectItems()) {
- // 直接遍历Item中的Column,绕过SelectExpressionItem
- item.accept(new SelectItemVisitorAdapter() {
- public void visit(Column column) {
- if (column.getTable() != null) {
- usedTables.add(column.getTable().getName());
- }
- }
- });
- }
- // 3. 提取WHERE条件中的表(用内置工具类)
- if (plainSelect.getWhere() != null) {
- List<String> whereTables = tablesNamesFinder.getTableList(plainSelect.getWhere());
- usedTables.addAll(whereTables);
- }
- return usedTables;
- }
- }
|