在最近的项目开发中,有这样一个需求,就是给定一个查询的sql,在where语句中添加几个条件语句。刚开始想的是,是否能用正则去做这个事情呢?其实不用语法树还是有一点困难的。

经过一系列google,看到了我们国产的druid里面sql parse的稳当还是比较详尽。具体参考这个文档SQL Parser

还是回到之前的需求:

public List<Map<String, Object>> search(String sql, Map<String, Object> conditions) {
List<Map<String, Object>> result = new ArrayList<>();
// SQLParserUtils.createSQLStatementParser可以将sql装载到Parser里面
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, JdbcUtils.MYSQL);
// parseStatementList的返回值SQLStatement本身就是druid里面的语法树对象
List<SQLStatement> stmtList = parser.parseStatementList(); SQLStatement stmt = stmtList.get(0);
if (stmt instanceof SQLSelectStatement) {
// convert conditions to 'and' statement
StringBuffer constraintsBuffer = new StringBuffer();
Set<String> keys = conditions.keySet();
Iterator<String> keyIter = keys.iterator();
if (keyIter.hasNext()) {
constraintsBuffer.append(keyIter.next()).append(" = ?");
}
while (keyIter.hasNext()) {
constraintsBuffer.append(" AND ").append(keyIter.next()).append(" = ?");
}
SQLExprParser constraintsParser = SQLParserUtils.createExprParser(constraintsBuffer.toString(), JdbcUtils.MYSQL);
SQLExpr constraintsExpr = constraintsParser.expr(); SQLSelectStatement selectStmt = (SQLSelectStatement) stmt;
// 拿到SQLSelect 通过在这里打断点看对象我们可以看出这是一个树的结构
SQLSelect sqlselect = selectStmt.getSelect();
SQLSelectQueryBlock query = (SQLSelectQueryBlock) sqlselect.getQuery();
SQLExpr whereExpr = query.getWhere();
// 修改where表达式
if (whereExpr == null) {
query.setWhere(constraintsExpr);
} else {
SQLBinaryOpExpr newWhereExpr = new SQLBinaryOpExpr(whereExpr, SQLBinaryOperator.BooleanAnd, constraintsExpr);
query.setWhere(newWhereExpr);
}
sqlselect.setQuery(query);
sql = sqlselect.toString();
Session session = sessionFactory.openSession();
SQLQuery sqlQuery = session.createSQLQuery(sql);
Collection values = conditions.values();
int index = 1;
for (Object value : values) {
sqlQuery.setParameter(index, value);
index++;
}
result = sqlQuery.list();
session.close();
} else {
throw new Exception("not select statement");
}
return result;
}

利用druid sql parser搞一些事情的更多相关文章

  1. com.alibaba.druid.sql.parser.ParserException: syntax error, QUES %, pos 80 like报错解决

    最近,把各应用的jdbc连接池统一从dbcp2改成了druid,运行时druid报sql解析错误,如下: select * from test         where 1=1         &l ...

  2. 【spring boot】集成了druid后,同样的mybatis模糊查询语句出错Caused by: com.alibaba.druid.sql.parser.ParserException: syntax error, error in :'name LIKE '%' ? '%'

    druid版本是 <!-- https://mvnrepository.com/artifact/com.alibaba/druid 数据库连接池--> <dependency> ...

  3. ORA-00907: 缺失右括号问题或com.alibaba.druid.sql.parser.ParserException: TODO :IDENTIFIER的原因

    以上只是说明错误的原因的一种.

  4. 利用 druid 的 sql parser 模块解析 sql 语句

    druid 是阿里开源在 github 上面的数据库连接池,里面有一个专门解析 sql 语句的模块   源码位置: https://github.com/alibaba/druid SQL Parse ...

  5. Druid SQL注入防御模块技术浅析

    官方参考: https://www.bookstack.cn/read/Druid/ffdd9118e6208531.md 前置知识 什么是Druid? Druid是一个高效的数据查询系统,主要解决的 ...

  6. Druid SQL 解析器概览

    概览 Druid 的官方 wiki 对 SQL 解析器部分的讲解内容并不多,但虽然不多,也有利于完全没接触过 Druid 的人对 SQL 解析器有个初步的印象. 说到解析器,脑海里便很容易浮现 par ...

  7. sql注入搞事情(连载一)

    SQL注入搞事情(连载一) 概述 写在最前面 为了有个合理的训练计划,山人准备长期开放自己的训练计划以及内容以供大家参考.山人专业是信息对抗技术,不是web方向的博客保证句句手打,如有问题请及时小窗. ...

  8. sql parser

    最近在整理很多SQL代码, 需要分析出每个SQL的目标表和源表各有哪些, 网上没有找到工作具, 打算写个工具. Java调研结果:1. 商业组件包 sqlparser 有试用版组件, 限制SQL少于1 ...

  9. Spark SQL catalyst概述和SQL Parser的具体实现

    之前已经对spark core做了较为深入的解读,在如今SQL大行其道的背景下,spark中的SQL不仅在离线batch处理中使用广泛,structured streamming的实现也严重依赖spa ...

随机推荐

  1. 编写 Model 层的代码

    创建 App 这里把所有 Model 划分为三类:blog 相关.配置相关和评论相关.这么分的好处是便于独立维护各个模块,也便于在开发时分配任务. blog App 创建一个名为 blog 的 app ...

  2. Java语言 List 和 Array 相互转换

    Java语言 List 和 Array 相互转换 List集合 转换为 Array数组 List集合 转换成 Array数组,有 2 种方式,代码如下: import java.util.ArrayL ...

  3. logging.basicConfig函数各参数:

    import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(line ...

  4. cpu切换线程上下文会耗费多少时间

    cpu切换线程上下文会耗费多少时间,有人在linux下面使用不同的cpu测试过,需要1000ns以上的时间 https://blog.tsunanet.net/2010/11/how-long-doe ...

  5. ES 知识点

    一.ES基于_version 进行乐观锁并发控制 post /index/type/id/_update?retry_on_conflict=5&version=6 1.内部版本号 第一次创建 ...

  6. office web apps安装部署,配置https,负载均衡(五)配置服务器场

    前提条件:您已经完成了域控制器的配置,拥有域账号,并且已经安装了OWA启动所需要的必要软件: 具体步骤可以参考: office web apps安装部署,配置https,负载均衡(一)背景介绍 off ...

  7. java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents...

    出现这个错误的原因是时区有问题,可以在mysql中执行命令: set global time_zone='+8:00'; 如上是修改为北京时间(GMT+0800). 查看修改: show variab ...

  8. 【POJ - 3087】Shuffle'm Up(模拟)

    Shuffle'm Up 直接写中文了 Descriptions: 给定两个长度为len的字符串s1和s2, 接着给出一个长度为len*2的字符串s12. 将字符串s1和s2通过一定的变换变成s12, ...

  9. ssh远程连接的故障排查详解

    排查故障: 1.两个机器之间是否通畅,看物理网络(网线网卡,IP是不是正确) ping ip -t 来检测物理网络是否通畅 通 不通 不通: 1.客户端到服务器端物理链路有问题 网卡 ,IP ,  网 ...

  10. [转帖]etcd 在超大规模数据场景下的性能优化

    etcd 在超大规模数据场景下的性能优化   阿里系统软件技术 2019-05-27 09:13:17 本文共5419个字,预计阅读需要14分钟. http://www.itpub.net/2019/ ...