利用druid sql parser搞一些事情

在最近的項目開發中,有這樣一個需求,就是給定一個查詢的sql,在where語句中添加幾個條件語句。剛開始想的是,是否能用正則去作這個事情呢?其實不用語法樹仍是有一點困難的。git

通過一系列google,看到了咱們國產的druid裏面sql parse的妥當仍是比較詳盡。具體參考這個文檔SQL Parsergithub

仍是回到以前的需求:sql

public List<Map<String, Object>> search(String sql, Map<String, Object> conditions) {
    List<Map<String, Object>> result = new ArrayList<>();
    // SQLParserUtils.createSQLStatementParser能夠將sql裝載到Parser裏面
    SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, JdbcUtils.MYSQL);
	// parseStatementList的返回值SQLStatement自己就是druid裏面的語法樹對象
    List<SQLStatement> stmtList = parser.parseStatementList();


    SQLStatement stmt = stmtList.get(0);
    if (stmt instanceof SQLSelectStatement) {
        // convert conditions to 'and' statement
        StringBuffer constraintsBuffer = new StringBuffer();
        Set<String> keys = conditions.keySet();
        Iterator<String> keyIter = keys.iterator();
        if (keyIter.hasNext()) {
            constraintsBuffer.append(keyIter.next()).append(" = ?");
        }
        while (keyIter.hasNext()) {
            constraintsBuffer.append(" AND ").append(keyIter.next()).append(" = ?");
        }
        SQLExprParser constraintsParser = SQLParserUtils.createExprParser(constraintsBuffer.toString(), JdbcUtils.MYSQL);
        SQLExpr constraintsExpr = constraintsParser.expr();

        SQLSelectStatement selectStmt = (SQLSelectStatement) stmt;
        // 拿到SQLSelect 經過在這裏打斷點看對象咱們能夠看出這是一個樹的結構
        SQLSelect sqlselect = selectStmt.getSelect();
        SQLSelectQueryBlock query = (SQLSelectQueryBlock) sqlselect.getQuery();
        SQLExpr whereExpr = query.getWhere();
        // 修改where表達式
        if (whereExpr == null) {
            query.setWhere(constraintsExpr);
        } else {
            SQLBinaryOpExpr newWhereExpr = new SQLBinaryOpExpr(whereExpr, SQLBinaryOperator.BooleanAnd, constraintsExpr);
            query.setWhere(newWhereExpr);
        }
        sqlselect.setQuery(query);
        sql = sqlselect.toString();
        Session session = sessionFactory.openSession();
        SQLQuery sqlQuery = session.createSQLQuery(sql);
        Collection values = conditions.values();
        int index = 1;
        for (Object value : values) {
            sqlQuery.setParameter(index, value);
            index++;
        }
        result = sqlQuery.list();
        session.close();
    } else {
        throw new Exception("not select statement");
    }
    return result;
}
相關文章
相關標籤/搜索