由于想要解决Mybatis分页插件中count查询效率问题,因为order by很影响效率,所以需要一种方式处理sql,将order by 语句去掉。

试了好几个sql解析工具,最后选择了fdb-sql-parser。

Maven依赖:

com.foundationdb

fdb-sql-parser

1.3.0

项目地址: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@1087be0

name: null

updateMode: UNSPECIFIED

statementType: SELECT

resultSet:

com.foundationdb.sql.parser.SelectNode@1fce2f2

isDistinct: false

resultColumns:

com.foundationdb.sql.parser.ResultColumnList@1978611

[0]:

com.foundationdb.sql.parser.ResultColumn@e2d858

exposedName: userid

name: userid

tableName: null

isDefaultColumn: false

type: null

expression:

com.foundationdb.sql.parser.ColumnReference@e9927a

columnName: userid

tableName: null

type: null

[1]:

com.foundationdb.sql.parser.ResultColumn@8fc7a7

exposedName: username

name: username

tableName: null

isDefaultColumn: false

type: null

expression:

com.foundationdb.sql.parser.ColumnReference@17ccb2f

columnName: username

tableName: null

type: null

[2]:

com.foundationdb.sql.parser.ResultColumn@1ff8de3

exposedName: password

name: password

tableName: null

isDefaultColumn: false

type: null

expression:

com.foundationdb.sql.parser.ColumnReference@bc448b

columnName: password

tableName: null

type: null

fromList:

com.foundationdb.sql.parser.FromList@383244

[0]:

com.foundationdb.sql.parser.FromBaseTable@16c1bce

tableName: sys_user

updateOrDelete: null

null

correlation Name: null

null

whereClause:

com.foundationdb.sql.parser.BinaryRelationalOperatorNode@95a253

operator: =

methodName: equals

type: null

leftOperand:

com.foundationdb.sql.parser.ColumnReference@1d41116

columnName: username

tableName: null

type: null

rightOperand:

com.foundationdb.sql.parser.CharConstantNode@1adfbe3

value: isea533

type: 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项目地址:

java 读fdb文件_JAVA - Sql解析工具fdb-sql-parser简单使用相关推荐

  1. SQL优化工具分享-SQL Tuning Expert Pro for Oracle Trial

    做开发离不开对于数据库的接触,也离不开对SQL的接触,一个优质的SQL,可以让系统性能提升到质的飞跃,一个糟糕的SQL,可以让系统奔溃.所以对于我们开发人员来说,很需要一个SQL性能优化工具,在这种情 ...

  2. java mysql 语句解析器_几种基于Java的SQL解析工具的比较与调用

    1.sqlparser http://www.sqlparser.com/ 优点:支持的数据库最多,除了传统数据库外还支持hive和greenplum一类比较新的数据库,调用比较方便,功能不错 缺点: ...

  3. Java读 写文本_java读文件写文件的方法

    java读文件写文件的方法 有的时候经常为真么读写文件最合理发愁,因为JAVA提过读写文件的方式太多了(C更甚至,fopen & open又有多少人傻傻分不清,更别说ReadFile了).今天 ...

  4. java 导出mdb文件_Java中Java生成mdb文件工具类

    package com.util; /**  * Java生成mdb文件[MS Access文件]  * 1. 在ClassPath下存一个空的blank.mdb. (也就是在你的项目中包含一个空白的 ...

  5. java读txt文件乱码_java读取txt文件时出现中文乱码怎么解决

    java读取txt文件时出现中文乱码怎么解决 发布时间:2020-06-25 15:27:31 来源:亿速云 阅读:105 作者:Leah java读取txt文件时出现中文乱码怎么解决?针对这个问题, ...

  6. java 读excel 流_Java 读取excel 文件流代码实例

    这篇文章主要介绍了Java 读取excel 文件流代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下public static voi ...

  7. java 解压文件_java实现解压zip文件,(亲测可用)!!!!!!

    项目结构: Util.java内容: package com.cfets.demo; import java.io.File; import java.io.FileOutputStream; imp ...

  8. java写入dat文件_java写入dat文件

    Java的输入输出包括字节流.文件流.对象流等,要注意区分不同流使用的不同类.字... Java的输入输出包括字节流.文件流.对象流等,要注意区分不同流使用的不同类.字... Java的输入输出包括字 ...

  9. Java常用的几种JSON解析工具

    一.Gson:Google开源的JSON解析库 1.添加依赖 <!--gson--> <dependency><groupId>com.google.code.gs ...

最新文章

  1. 使用 expect 命令执行自动分发系统
  2. TQ2440的学习——UBOOT移植(串口控制台的支持)
  3. c++冒泡排序代码_C/C++基础之冒泡排序
  4. lsof找回误删的文件
  5. tcp协议中的长连接和短连接服务器,谈谈HTTP协议中的短轮询、长轮询、长连接和短链接...
  6. css的再深入7(更新中···)
  7. 计算机程序辅助拼货,拼货
  8. presto 正则提取函数
  9. Jquery实现全选反选和省城市联动效果
  10. OpenContrail 体系
  11. 软件开发常用英文词汇
  12. python自动化测试绕过手机验证码
  13. 高级信息系统项目管理师(高项)高分通过经验分享
  14. 如何在Word小方框里打勾
  15. 系分架构 - 软件架构设计
  16. [翻译]为EXPRESSION WEB 4添翼—如何支持HTML5设计开发!
  17. 社团管理——原型设计
  18. ORA-01261 和 ORA-01262
  19. 维骨力 Vinteail-S Capsules
  20. 独家专访蚂蚁金服旗下蚂蚁佐罗CEO Toby Rush,揭秘识别同卵多胞胎背后的技术力量

热门文章

  1. 一个27岁没文凭,想去努力自学编程,有机会成为程序员吗?
  2. 河南科技大学计算机基础题库,计算机基础试卷(河南科技大学)
  3. 计算机应用基础试卷分析报告,试卷分析计算机应用基础
  4. 基于java房屋租赁平台计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
  5. 03pe修改计算机名称,[U盘PE教程]玩转PE内置注册表(基于NT6.0)
  6. WebMatrix (1)
  7. 如何避免网站改版造成的排名影响
  8. candidate key, primary key, superkey的区别
  9. 56页智慧园区智能化弱电设计方案-智慧园区整体解决方案
  10. 还在一直使用Photoshop吗?在线PS处理图片更简单方便