druid 解析select查询sql获取表名,字段名,where条件

该代码段展示了如何解析SQL查询语句并生成QueryModelInfo对象。它首先根据数据库类型解析SQL语句,然后获取表名、查询列和过滤条件,并将这些信息封装到QueryModelInfo对象中,用于后续的数据操作。
摘要由CSDN通过智能技术生成
/**
 * 解析select sql生成QueryModelInfo
 * @param dbTypeName  mysql, oracle...
 * @param selectSql
 * @return
 */
public static QueryModelInfo parse(String dbTypeName, String selectSql) {
    QueryModelInfo queryModelInfo = new QueryModelInfo();
    DbType dbType = DbType.valueOf(dbTypeName.toLowerCase());
    List<SQLStatement> statementList = SQLUtils.parseStatements(selectSql, dbType);
    //final String format = SQLUtils.format(selectSql, dbType, SQLUtils.DEFAULT_FORMAT_OPTION);
    //log.debug("selectSql format = "+format);
    for (SQLStatement statement : statementList) {
        if (statement instanceof SQLSelectStatement) {
            SchemaStatVisitor visitor = new SchemaStatVisitor(dbType);
            statement.accept(visitor);

            //解析表名
            SQLSelectStatement selectStatement = (SQLSelectStatement) statement;
            SQLSelectQueryBlock queryBlock =  selectStatement.getSelect().getFirstQueryBlock();
            SQLTableSource from = queryBlock.getFrom();
            SQLExprTableSource sqlExprTableSource = (SQLExprTableSource) from;
            String tableName = sqlExprTableSource.getTableName();
            queryModelInfo.setTableName(tableName);

            //查询列
            Collection<TableStat.Column> columns = visitor.getColumns();
            List<String> columnList = new ArrayList<>();
            columns.stream().forEach(row -> {
                if(row.isSelect()){
                    //保存select字段
                    columnList.add(row.getName());
                }
            });
            queryModelInfo.setColumnList(columnList);

            //查询过滤条件
            List<TableStat.Condition> conditions = visitor.getConditions();
            Map<String, SysQueryMethodEnum> whereMap = new HashMap<>();
            conditions.stream().forEach(row -> {
                String columnName = row.getColumn().getName();
                String operator = row.getOperator();
                if("=".equalsIgnoreCase(operator)){
                    whereMap.put(columnName, SysQueryMethodEnum.eq);
                }else if("LIKE".equalsIgnoreCase(operator)){
                    whereMap.put(columnName, SysQueryMethodEnum.like);
                }else{
                    log.warn("un support operator "+operator+"; row = "+row);
                }
            });
            queryModelInfo.setWhereMap(whereMap);
            break;
        }
    }
    return queryModelInfo;
}

//解析返回对象

public class QueryModelInfo {

    private String tableName;
    private List<String> columnList;
    private Map<String, SysQueryMethodEnum> whereMap;

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public List<String> getColumnList() {
        return columnList;
    }

    public void setColumnList(List<String> columnList) {
        this.columnList = columnList;
    }

    public Map<String, SysQueryMethodEnum> getWhereMap() {
        return whereMap;
    }

    public void setWhereMap(Map<String, SysQueryMethodEnum> whereMap) {
        this.whereMap = whereMap;
    }
}

 

 

以下是使用druid实现sql解析解析select字段的依赖的表名字段名的Java代码: ```java import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; import com.alibaba.druid.sql.parser.ParserException; import java.util.ArrayList; import java.util.List; public class SqlParser { public static void main(String[] args) { String sql = "SELECT a.id, a.name, b.age FROM table_a a LEFT JOIN table_b b ON a.id = b.id WHERE a.gender = 'M'"; List<String> tableFields = parseSql(sql); for (String tableField : tableFields) { System.out.println(tableField); } } public static List<String> parseSql(String sql) { List<String> tableFields = new ArrayList<>(); try { SQLStatement stmt = new MySqlStatementParser(sql).parseStatement(); if (stmt instanceof SQLSelectStatement) { SQLSelectStatement selectStmt = (SQLSelectStatement) stmt; SQLSelect select = selectStmt.getSelect(); List<SQLSelectItem> selectItems = select.getSelectList(); for (SQLSelectItem selectItem : selectItems) { SQLExpr expr = selectItem.getExpr(); String tableField = parseExpr(expr); if (tableField != null) { tableFields.add(tableField); } } } } catch (ParserException e) { e.printStackTrace(); } return tableFields; } private static String parseExpr(SQLExpr expr) { if (expr instanceof SQLPropertyExpr) { SQLPropertyExpr propertyExpr = (SQLPropertyExpr) expr; String owner = propertyExpr.getOwner().toString(); String column = propertyExpr.getName(); return owner + "." + column; } else if (expr instanceof SQLIdentifierExpr) { SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr; String column = identifierExpr.getName(); return column; } else if (expr instanceof SQLAllColumnExpr) { return "*"; } else { return null; } } } ``` 以上代码实现了将输入的SQL语句解析出所有select字段依赖的表名字段名,并以"表名.字段名"的形式存储在一个List<String>中返回。例如,对于输入的SQL语句"SELECT a.id, a.name, b.age FROM table_a a LEFT JOIN table_b b ON a.id = b.id WHERE a.gender = 'M'",解析出的select字段依赖的表名字段名为: - table_a.id - table_a.name - table_b.age 注意,该代码仅支持解析MySQL语法的SQL语句,其他数据库SQL语句需要根据具体语法进行相应修改。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星梦天河

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值