springboot引入druid解析sql

一、前言

在开发中,有时我们可能会需要获取SQL中的表名,那么因为不同的数据源类型SQL会存在部分差异,那么我们就可以使用alibaba 的druid包实现不同的数据源类型的sql解析。

二、引入相关maven依赖

csharp 复制代码
<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>

三、通过工具类SqlUtils实现对SQL的解析。

csharp 复制代码
public class QualitySqlUtils {

	  /**
     *  根据sql及数据源类型获取表名
     */
	 public static List<String> getSelectSqlTable(String sql, String dbType) {
        List<String> tableList = new ArrayList<>();
        List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);
        SchemaStatVisitor visitor;
        for (SQLStatement sqlStatement : stmtList) {
            if (DbType.mysql.name().equalsIgnoreCase(dbType)) {
                visitor = new MySqlSchemaStatVisitor();
            } else if (DbType.hive.name().equalsIgnoreCase(dbType)) {
                visitor = new HiveSchemaStatVisitor();
            } else if (DbType.postgresql.name().equalsIgnoreCase(dbType)) {
                visitor = new PGSchemaStatVisitor();
            } else if (DbType.oracle.name().equalsIgnoreCase(dbType)) {
                visitor = new OracleSchemaStatVisitor();
            } else {
                visitor = new SchemaStatVisitor(DbType.of(dbType));
            }
            sqlStatement.accept(visitor);
            Map<TableStat.Name, TableStat> tables = visitor.getTables();
            for (Map.Entry<TableStat.Name, TableStat> entry: tables.entrySet()){
                String value = entry.getValue().toString();
                if (StringUtils.isNotBlank(value)) {
                    tableList.add(entry.getKey().getName());
                }
            }
        }
        return tableList;
    }
    /**
    * 根据sql获取查询的字段
    */
    public static Map<String, String> getSelectSqlColumn(String sql, String dbType) {
        Map<String, String> columnMap = new HashMap<>();
        List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);
        for (int i = 0; i < stmtList.size(); i++) {
            SQLStatement stmt = stmtList.get(i);
            if (stmt instanceof SQLSelectStatement) {
                SQLSelectStatement sqlSelectStatement = (SQLSelectStatement) stmt;
                SQLSelect select = sqlSelectStatement.getSelect();
                SQLSelectQueryBlock query = (SQLSelectQueryBlock) select.getQuery();
                List<SQLSelectItem> selectList = query.getSelectList();
                selectList.forEach(item->{
                    columnMap.put(item.getExpr().toString(), item.getAlias());
                });
            }
        }
        return columnMap;
    }
}

三、测试结果

csharp 复制代码
public class testDemo{
	
    public static void main(String[] args) {
        String sql = "select t.* from table1 as t left join table2 t2 on t.id = t2.id";
        List<String> tableList =getSelectSqlTable(sql, "mysql");
        System.out.println("获取到的表名: "+tableList);
    }
}

运行结果如下:

大家感兴趣可以尝试下。

相关推荐
Mandy的名字被占用了12 小时前
晨风AI+知识付费系统|学练考全闭环,重构教育变现新模式
人工智能·后端
why技术12 小时前
分享一套我一直在使用的 AICoding 组合拳,小而美的典范。
前端·后端·ai编程
GetcharZp13 小时前
SRS实战:一个开源流媒体服务,支持6大协议,80ms低延迟,轻松搭建自己的直播平台
后端
Csvn13 小时前
📊 SQL 入门 Day 7:子查询 — 查询中的查询
后端·sql
IT_陈寒16 小时前
为什么我的JavaScript异步代码总是不按顺序执行?
前端·人工智能·后端
星栈16 小时前
Node 框架怎么选?Express、Koa、Egg、NestJS 场景化选型指南
后端·node.js
锋行天下17 小时前
打造企业内部知识库系统RAG全栈项目
前端·后端·架构
音符犹如代码17 小时前
后端视角看 EventBus:发布订阅总线的原理、场景与用法
java·spring boot·guava
码事漫谈18 小时前
Kimi K3 真实体验:全网评价整理,优缺点一次性说清楚
后端
Fanta丶18 小时前
16.Activiti8 SpringBoot3.X 部署与测试
后端