JAVA - Sql解析工具fdb-sql-parser簡單使用

來源:互聯網
上載者:User

標籤:mybatis   sql-parser   sql解析   sql結構   

由於想要解決Mybatis分頁外掛程式中count查詢效率問題,因為order by很影響效率,所以需要一種方式處理sql,將order by 語句去掉。  


試了好幾個sql解析工具,最後選擇了fdb-sql-parser。


Maven依賴:

<dependency>    <groupId>com.foundationdb</groupId>    <artifactId>fdb-sql-parser</artifactId>    <version>1.3.0</version></dependency>

項目地址:https://github.com/FoundationDB/sql-parser


解析方法:  

package com.isea533.sql;import com.foundationdb.sql.parser.SQLParser;import com.foundationdb.sql.parser.StatementNode;public class Parser {    public static void main(String[] args) throws Exception {        SQLParser parser = new SQLParser();        StatementNode stmt = parser.parseStatement(                "select userid,username,password " +                "from sys_user where username = 'isea533'");        stmt.treePrint();    }}

調用treePrint()可以列印出sql的結構:

[email protected]name: nullupdateMode: UNSPECIFIEDstatementType: SELECTresultSet: [email protected]isDistinct: falseresultColumns: [email protected][0]:[email protected]exposedName: useridname: useridtableName: nullisDefaultColumn: falsetype: nullexpression: [email protected]columnName: useridtableName: nulltype: null[1]:[email protected]exposedName: usernamename: usernametableName: nullisDefaultColumn: falsetype: nullexpression: [email protected]columnName: usernametableName: nulltype: null[2]:[email protected]exposedName: passwordname: passwordtableName: nullisDefaultColumn: falsetype: nullexpression: [email protected]columnName: passwordtableName: nulltype: nullfromList: [email protected][0]:[email protected]tableName: sys_userupdateOrDelete: nullnullcorrelation Name: nullnullwhereClause: [email protected]operator: =methodName: equalstype: nullleftOperand: [email protected]columnName: usernametableName: nulltype: nullrightOperand: [email protected]value: isea533type: CHAR(7) NOT NULL

解析後的結果stmt結構挺複雜的,像上面這張結構是由很多不同類型的Node嵌套而成的,想要在這種結構上做什麼改動比較麻煩,並且許多屬性沒有提供完整的setter和getter方法,使用反射處理起來比較麻煩。對於不同類型的Node判斷起來相當的麻煩。至於有多麻煩,去看NodeToString這個類就明白了。  


除瞭解析SQL之外,還能將上面這種結構形式的資料轉換為sql。使用如下方法:  

NodeToString unparser = new NodeToString();String sql = unparser.toString(stmt);

我曾經花了不少時間在處理Node結構上,如果想通過修改結構來獲得最終沒有order by的sql,因為SQL可以有很多種變化和形式,所以需要處理的相當複雜。最後不得不放棄這種方式。


後來在看到NodeToString時,想到既然這個類將結構輸出成sql了,那麼他一定也處理了這種複雜的結構。進入NodeToString後直接尋找order by,發現:

protected String orderByList(OrderByList node) throws StandardException {    return "ORDER BY " + nodeList(node);}
這裡應該就是處理sql中order by的地方,很快就複製源碼,只把上面這個方法修改為return "";,然後測試發現沒問題。  


在之後看到類中好多的protected方法時,才察覺到應該採用繼承的方式來擴充,同時把解析sql的方法寫到這個方法中:  

package com.isea533.sql;import com.foundationdb.sql.StandardException;import com.foundationdb.sql.parser.OrderByList;import com.foundationdb.sql.parser.SQLParser;import com.foundationdb.sql.parser.StatementNode;import com.foundationdb.sql.unparser.NodeToString;public class RemoveOrderByUnParser extends NodeToString {    private static final SQLParser PARSER = new SQLParser();    public String removeOrderBy(String sql) throws StandardException {        StatementNode stmt = PARSER.parseStatement(sql);        return toString(stmt);    }    @Override    protected String orderByList(OrderByList node) throws StandardException {        return "";    }}

想要去掉Order by 的時候調用removeOrderBy方法就可以。


從一開始浪費那麼多時間,到最後這麼簡單的方法就能實現,這種情況雖然很常見,但是感覺很複雜。


就好比遇到了一個問題,有些人費盡各種方法最後解決了,有些人直接看到了答案。兩種情況得到的東西是不一樣的,解決問題的過程有時候比解決方案更重要。


這篇檔案從頭到尾主要說的可能就是去掉了order by,肯定不是所有人解析sql就是為了這個目的,但是這是一種思路,使用這個sqlparser,你可以從NodeToString入手,通過重寫這裡面的方法,應該能夠滿足大多數的需求了。  


最後想說,Mybatis分頁外掛程式又更新了,增加了count查詢時對sql的最佳化,最佳化方法就是本文的內容。


Mybatis分頁外掛程式是一個努力讓Mybatis物理分頁更簡單的開源項目,如果你在使用Mybatis,不妨看看這個分頁外掛程式。


Mybatis項目地址:

https://github.com/pagehelper/Mybatis-PageHelper


http://git.oschina.net/free/Mybatis_PageHelper

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.