JAVA - Sql解析工具fdb-sql-parser简单使用
来源:互联网 发布:企业办公网络组网方案 编辑:程序博客网 时间:2024/06/05 10:07
由于想要解决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的结构:
com.foundationdb.sql.parser.CursorNode@1087be0name: nullupdateMode: UNSPECIFIEDstatementType: SELECTresultSet: com.foundationdb.sql.parser.SelectNode@1fce2f2isDistinct: falseresultColumns: com.foundationdb.sql.parser.ResultColumnList@1978611[0]:com.foundationdb.sql.parser.ResultColumn@e2d858exposedName: useridname: useridtableName: nullisDefaultColumn: falsetype: nullexpression: com.foundationdb.sql.parser.ColumnReference@e9927acolumnName: useridtableName: nulltype: null[1]:com.foundationdb.sql.parser.ResultColumn@8fc7a7exposedName: usernamename: usernametableName: nullisDefaultColumn: falsetype: nullexpression: com.foundationdb.sql.parser.ColumnReference@17ccb2fcolumnName: usernametableName: nulltype: null[2]:com.foundationdb.sql.parser.ResultColumn@1ff8de3exposedName: passwordname: passwordtableName: nullisDefaultColumn: falsetype: nullexpression: com.foundationdb.sql.parser.ColumnReference@bc448bcolumnName: passwordtableName: nulltype: nullfromList: com.foundationdb.sql.parser.FromList@383244[0]:com.foundationdb.sql.parser.FromBaseTable@16c1bcetableName: sys_userupdateOrDelete: nullnullcorrelation Name: nullnullwhereClause: com.foundationdb.sql.parser.BinaryRelationalOperatorNode@95a253operator: =methodName: equalstype: nullleftOperand: com.foundationdb.sql.parser.ColumnReference@1d41116columnName: usernametableName: nulltype: nullrightOperand: com.foundationdb.sql.parser.CharConstantNode@1adfbe3value: 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
- JAVA - Sql解析工具fdb-sql-parser简单使用
- JAVA - Sql解析工具fdb-sql-parser简单使用
- JAVA - Sql解析工具jsqlparser简单使用
- JAVA - Sql解析工具jsqlparser简单使用
- SQL解析利器General SQL Parser
- sql parser
- 使用java sql parser插件Jsqlparser 实例(二)
- phpMyAdmin中sql-parser组件的使用
- phpMyAdmin中sql-parser组件的使用
- phpMyAdmin中sql-parser组件的使用
- jspSqlparser解析sql语句的简单使用
- stanford parser使用工具
- 使用openjdk的语法解析器(Parser)解析java源代码
- 使用Log Parser将IIS日志导入SQL分析
- 使用SQL*Plus工具
- PL/SQL工具使用
- 使用sql*plus工具
- java 解析sql脚本
- HDU 4004 The Frog's Games(基本算法-贪心,搜索-二分)
- 赵云传
- CSS 子元素选择器
- 毕业论文答辩应注意的几个问题
- Stellaris LM3Sxxx------DMA【3-2】
- JAVA - Sql解析工具fdb-sql-parser简单使用
- 线段树特殊标记hdu4027(网络赛)
- poj 3262贪心
- 怎样在WIN7系统下安装IIS
- Ubuntu在VMWare上不能使用共享文件夹
- vs2010 打开项目时 不能加载包
- C语言字符串输入,gets函数的缺点以及解决方法
- 编程之美--3.3计算字符串的相似度
- spring mvc 文件上传