jsqlparser是一个java的SQL语句解析器,基于它可以实现很多之前无法完成的工作。

     <!-- maven 依赖库引用 --><dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifactId><version>4.5</version></dependency

比如如下的SQL语句:

SELECT person.id,person.name,group.name  FROM person JOIN group ON person.group_id = group.id WHERE person.birthdate > '1980-01-01'

在MySQL中执行没有任何问题,但是如果用phoenix在HBase数据库中执行,语法是过不去的。因为phoenix中默认字段名,表名都是大写的,如果指定小写的字段和表名,需要加双引号.

SELECT "person"."id","person"."name","group"."name"  FROM "person" JOIN "group" ON "person"."group_id" = "group"."id" WHERE "person"."birthdate" > '1980-01-01'

对于一个SQL语句如何能根据数据库的要求为字段名和表名自动加引号或双引号,就需要用到jsqlparser这个利器。

jsqlparser解析一个SQL语句后会生成一个抽象语法树(AST-- Abstract Syntax Tree)对象SimpleNode,并提供了用于遍历AST的接口CCJSqlParserVisitor,应用层只要实现这个接口我们就可以通过接口方法得到想要的SQL语法元素节点对象,比如ColumnTable。当然还可以根据实际需要干点别的。
以下就以为字段名和表名加双引号为例,说明如何用CCJSqlParserVisitor来遍历所有AST节点

 @Testpublic void test10ParseVisitor() throws ParseException {String sql = "SELECT person.id,person.name,group.name  FROM person JOIN group ON person.group_id = group.id WHERE person.birthdat > '1980-01-01'";/** 创建SQL语句解析器实例 */CCJSqlParser parser = CCJSqlParserUtil.newParser(sql);/** 解析SQL语句 */Statement stmt = parser.Statement();/** 使用 LogVisiter对象遍历AST的所有节点 */parser.getASTRoot().jjtAccept(new LogVisitor(), null);System.out.printf("sql--> %s",stmt);}/*** 遍历所有节点的{@link net.sf.jsqlparser.parser.CCJSqlParserVisitor} 接口实现类* @author guyadong**/static class LogVisitor extends CCJSqlParserDefaultVisitor{@Overridepublic Object visit(SimpleNode node, Object data) {Object value = node.jjtGetValue();/** 根据节点类型找出表名和字段名节点,对名字加上双引号 */if (node.getId() == CCJSqlParserTreeConstants.JJTCOLUMN) {               System.out.printf("column %s",value.toString());Column column = (Column)value;column.setColumnName("\"" + column.getColumnName() + "\"");Table table = column.getTable();if(null != table){table.setName("\"" + table.getName() + "\"");}} else if (node.getId() == CCJSqlParserTreeConstants.JJTTABLE) {System.out.printf("table %s",value.toString());Table table = (Table)value;if(null != table){table.setName("\"" + table.getName() + "\"");}}else if(null != value){/** 其他类型节点输出节点类型值,Java类型和节点值 */System.out.printf("%d %s %s",node.getId(),value.getClass().getSimpleName(),value.toString());}return super.visit(node, data);}}

输出:

6 PlainSelect SELECT person.id, person.name, group.name FROM person JOIN group ON person.group_id = group.id WHERE person.birthdat > ‘1980-01-01’
9 SelectExpressionItem person.id
column person.id
9 SelectExpressionItem person.name
column person.name
9 SelectExpressionItem group.name
column group.name
table person
10 Join JOIN group ON person.group_id = group.id
table group
14 EqualsTo person.group_id = group.id
column person.group_id
column group.id
14 GreaterThan person.birthdat > ‘1980-01-01’
column person.birthdat
20 StringValue ‘1980-01-01’
sql–> SELECT “person”.“id”, “person”.“name”, “group”.“name” FROM “person” JOIN “group” ON “person”.“group_id” = “group”.“id” WHERE “person”.“birthdat” > ‘1980-01-01’

从上面最后一行输出可以看到,jsqlparser已经精确的将SQL语句中所有表名和字段名都自动加了双引号。

参考资料

《Parsing table and column names from SQL/HQL Java》

jsqlparser:基于抽象语法树(AST)遍历SQL语句的语法元素相关推荐

  1. 学习SQL应知道的动态SQL语句基本语法

    学习SQL应知道的动态SQL语句基本语法 1 .普通SQL语句可以用Exec执行 9Kp=A   ' CdaFr1   eg: Select * from tableName Wsc+A:<&q ...

  2. Sql Server实用操作-动态sql语句基本语法

    如何将exec执行结果放入变量中? declare @num int, @sqls nvarchar(4000) set @sqls='select @a=count(*) from tableNam ...

  3. 动态sql语句基本语法

    --******************          动态sql语句基本语法           *****************------------------------------- ...

  4. 动态SQL语句的语法

    动态SQL是在运行时生成和执行SQL语句的编程方法.动态是和静态相对而言的.静态SQL指的是在代码编译时刻就已经包含在代码中的那些已经充分明确的固定的SQL语句. PL/SQL提供了两种方式来编写动态 ...

  5. mysql创建多表视图sql语句_SQL语法(包括建库、建表、建视图、查询、增加、删除、修改)...

    SQL语法(包括建库.建表.建视图.查询.增加.删除.修改) SQL分类: DDL-数据定义语言(CREATE,ALTER,DROP,DECLARE) DML-数据操纵语言(SELECT,DELETE ...

  6. 分布式事务seat对于sql语句的语法要求

    昨天工作中,出现了一个系统异常 系统原因如下: io.seata.common.exception.NotSupportYetException: not support the syntax of ...

  7. SQL语句基础语法——简单的增,删,查,改

           SQL语句全称为Structured Query Language,翻译为结构化查询语句,是面向数据库的语句.但是不同的数据库会有一些出入,使用数据库时应阅读相应的数据库手册.      ...

  8. php原生sql语法,thinkphp执行原生SQL语句的实现方法

    怎样在thinkphp里面执行原生的sql语句? $Model = new Model();//或者 $Model = D(); 或者 $Model = M(); $sql = "selec ...

  9. iOS逆向:【代码混淆】1、基于编译器混淆静态库(StaticLib)2、字符串加密:使用clang-c接口将源代码转换成抽象语法树,并对抽象语法树进行遍历和分析,分析代码中的字符串,并进行加密处理。

    文章目录 前言 I .LLVM编译一个源文件的过程 1.1.预处理 1.2.将符号化后的内容转化为一棵解析树 (parse tree) 1.3.将 AST 转换为更低级的中间码 (LLVM IR) 1 ...

最新文章

  1. 数据库连接池到底应该设多大?
  2. 随机森林为何要有放回抽样
  3. Ubuntu中Samba的安装配置和使用[图文]
  4. python程序员工作怎样-现在Python就业薪资高吗?Python程序员前景怎么样?
  5. Docker logs 命令
  6. 《游戏大师Chris Crawford谈互动叙事》一22.1 互动叙事前途无量
  7. 解决ubuntu首次安装Mysql之后,首次登录出现ERROR 1698 (28000): Access denied for user 'root'@'localhost'的方法
  8. JAVA JDK1.5-1.9新特性
  9. Bootstrap基础3(表单)
  10. Oracle命令--查询语句
  11. equals()与hashCode()方法协作约定
  12. Windows令牌窃取提权和烂土豆提权学习
  13. AD检查步骤及其顺序
  14. usb芯片+android+驱动,PL2303芯片驱动
  15. electron-vue中调用系统屏幕键盘(linux与windows)
  16. php mud游戏源码,mud手游源码,mud安卓端源码,谁与争锋mud源码:关于MUD纯文字游戏架设(回答得好加分100)(开源mud游戏框架)-南开游戏网...
  17. ZXing之生成条形码
  18. 有卡却显示无服务器,为什么卡一直显示无服务
  19. Oracle RushQL勒索病毒恢复方法
  20. 时间序列中Hurst指数的计算(python代码)

热门文章

  1. 董明珠说向雷军学习!股票从上市的17块跌到8块,小米不行了吗?
  2. 苹果数据线充电线损坏自己修
  3. 求解雅克比矩阵的符号运算
  4. 转载:有关京东和刘强东的一篇文章
  5. 5 年工作经验,容器与 Pod 的区别和联系都说不清,你敢信?
  6. 小程序到期了怎么办?
  7. TSC TTP-243E-Pro打印机纸张打印错位的解决办法
  8. 高通发布两款64位处理器骁龙Snapdragon 810/808
  9. CSDN会员自动续费协议
  10. Java中构造方法的详细介绍