使用Druid SQL Parser解析SQL 获取多个来源表和对应的目标表


        com.alibaba
        druid
        1.2.6
    




String sql ="";
SQLStatement stmt = SQLUtils.parseSingleStatement(sql, DbType.mysql); // 将 SQL 语句解析为 SQLStatement 对象
    if (stmt instanceof SQLInsertStatement) {
        SQLInsertStatement insert = (SQLInsertStatement) stmt;
        String targetTable = insert.getTableName().getSimpleName(); // 获取目标表名
        SQLSelect source = insert.getQuery(); // 找出来源表查询
        List sourceTables = new ArrayList<>(); // 存储来源表的列表
        Set sourceTableAliases = new HashSet<>(); // 存储来源表别名的集合
        getSources(source.getQueryBlock().getFrom(), sourceTables, sourceTableAliases); // 获取主表及其关联的所有来源表
        Map sourceTableMap = new HashMap<>(); // 存储来源表与对应别名或表名的映射关系
        for (SQLTableSource sourceTable : sourceTables) {
            if (sourceTable instanceof SQLExprTableSource) { // 如果是基本表,则直接获取表名
                SQLExprTableSource exprTableSource = (SQLExprTableSource) sourceTable;
                String sourceTableName = exprTableSource.getName().getSimpleName();
                sourceTableMap.put(sourceTable, sourceTableName);
            } else if (sourceTable instanceof SQLSubqueryTableSource) { // 如果是子查询,则递归解析
                SQLSubqueryTableSource subqueryTableSource = (SQLSubqueryTableSource) sourceTable;
                SQLSelect subquery = subqueryTableSource.getSelect();
                List subquerySources = new ArrayList<>();
                Set subqueryAliases = new HashSet<>();
                getSources(subquery.getQueryBlock().getFrom(), subquerySources, subqueryAliases);
                for (SQLTableSource subquerySource : subquerySources) {
                    if (!sourceTables.contains(subquerySource)) {
                        sourceTables.add(subquerySource); // 将子查询中的来源表加入列表中
                    }
                    String alias = subqueryAliases.contains(subquerySource.getAlias()) ? subquerySource.getAlias() : null; // 子查询中的来源表可能存在别名,进行处理
                    if (alias == null && subquerySource instanceof SQLExprTableSource) { // 如果没有别名,则使用表名作为键
                        SQLExprTableSource exprTableSource = (SQLExprTableSource) subquerySource;
                        alias = exprTableSource.getName().getSimpleName();
                    }
                    sourceTableMap.put(subquerySource, alias);
                }
            } else {
                throw new UnsupportedOperationException("Unsupported table type: " + sourceTable.getClass());
            }
        }
        for (SQLTableSource sourceTable : sourceTables) {
            String sourceTableName = sourceTableMap.get(sourceTable);
            System.out.println("来源表: " + sourceTableName);
        }
        System.out.println("目标表: " + targetTable);
    }



/**
 *
 * @param tableSource 存储来源表的列表
 * @param sources 存储来源表别名的集合
 * @param aliases 存储来源表和对应别名或者表名的映射关系
 */
private static void getSources(SQLTableSource tableSource, List sources, Set aliases) {
    if (tableSource == null) {
        return;
    }
    if (tableSource instanceof SQLJoinTableSource) {
        SQLJoinTableSource join = (SQLJoinTableSource) tableSource;

        getSources(join.getLeft(), sources, aliases);
        getSources(join.getRight(), sources, aliases);
    } else {
        if (!sources.contains(tableSource)) {
            sources.add(tableSource);
            String alias = tableSource.getAlias();
            if (alias != null) {
                aliases.add(alias);
            }
        }
    }
}

你可能感兴趣的:(sql,java,数据库)