一、sqlparserjava
http://www.sqlparser.com/mysql
優勢:支持的數據庫最多,除了傳統數據庫外還支持hive和greenplum一類比較新的數據庫,調用比較方便,功能不錯git
缺點:收費,500$起github
二、Apache Calcitesql
一個構建JDBC或者ODBC訪問數據庫的框架,經過自定義一些adapter經過sql訪問任意類型的數據數據庫
優勢:開源oracle
缺點:sql解析只是一小部分功能,且只支持通用的文法樹,沒法對不一樣數據庫提供本地化支持框架
三、druidmaven
阿里的一個開源項目,實際上是個JDBC,可是能夠經過這個JDBC統計經過它提交的各類sql執行狀況等信息,對提交sql進行監控統計sqlserver
主頁:https://github.com/alibaba/druid
咱們用到的SQL-Parser是它的一個組件:
https://github.com/alibaba/druid/wiki/SQL-Parser
支持數據庫不算少:
db2
mysql
odps
oracle
phoenix
postgresql
sqlserver
transact
不過部分語法支持還處於開發中,好比,不支持解析postgresql的begin/commit語法,不支持group by 1, 2這種指定字段的語法。。。-_||
編譯:
一開始懶得安裝maven使用javac編譯,結果出了一堆代碼中包含的中文編碼問題,花時間研究編碼不如乖乖下載安裝maven……-_-
在源碼根目錄下直接執行mvn:
mvn install -Dmaven.javadoc.skip=true -Dmaven.test.skip=true
編譯後代碼目錄多出target子目錄,裏面有class和代碼文件的jar包
調用很簡單
1 package parse; 2 3 import java.util.Iterator; 4 import java.util.List; 5 import java.util.Map; 6 import java.util.Set; 7 8 import com.alibaba.druid.sql.SQLUtils; 9 import com.alibaba.druid.sql.ast.SQLStatement; 10 import com.alibaba.druid.sql.dialect.postgresql.visitor.PGSchemaStatVisitor; 11 import com.alibaba.druid.stat.TableStat.*; 12 import com.alibaba.druid.stat.*; 14 import com.alibaba.druid.util.JdbcConstants; 15 16 17 public class testparse { 18 19 public static void main(String[] args) { 20 21 String sql= "" 22 + "insert into tar select * from boss_table bo, (" 23 + "select a.f1, ff from emp_table a " 24 + "inner join log_table b " 25 + "on a.f2 = b.f3" 26 + ") f " 27 + "where bo.f4 = f.f5 " 28 + "group by bo.f6 , f.f7 having count(bo.f8) > 0 " 29 + "order by bo.f9, f.f10;" 30 + "select func(f) from test1; " 31 + ""; 32 String dbType = JdbcConstants.POSTGRESQL; 33 34 //格式化輸出 35 String result = SQLUtils.format(sql, dbType); 36 System.out.println(result); // 缺省大寫格式 37 List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType); 38 39 //解析出的獨立語句的個數 40 System.out.println("size is:" + stmtList.size()); 41 for (int i = 0; i < stmtList.size(); i++) { 42 43 SQLStatement stmt = stmtList.get(i); 44 45 PGSchemaStatVisitor visitor = new PGSchemaStatVisitor(); 46 stmt.accept(visitor); 47 Map<String, String> aliasmap = visitor.getAliasMap(); 48 for (Iterator iterator = aliasmap.keySet().iterator(); iterator.hasNext();) { 49 String key = iterator.next().toString(); 50 System.out.println("[ALIAS]" + key + " - " + aliasmap.get(key)); 51 } 52 Set<Column> groupby_col = visitor.getGroupByColumns(); 53 // 54 for (Iterator iterator = groupby_col.iterator(); iterator.hasNext();) { 55 Column column = (Column) iterator.next(); 56 System.out.println("[GROUP]" + column.toString()); 57 } 58 //獲取表名稱 59 System.out.println("table names:"); 60 Map<Name, TableStat> tabmap = visitor.getTables(); 61 for (Iterator iterator = tabmap.keySet().iterator(); iterator.hasNext();) { 62 Name name = (Name) iterator.next(); 63 System.out.println(name.toString() + " - " + tabmap.get(name).toString()); 64 } 65 //System.out.println("Tables : " + visitor.getCurrentTable()); 66 //獲取操做方法名稱,依賴於表名稱 67 System.out.println("Manipulation : " + visitor.getTables()); 68 //獲取字段名稱 69 System.out.println("fields : " + visitor.getColumns()); 70 } 71 72 } 73 74 }