利用druid sql parser搞一些事情
在最近的项目开发中,有这样一个需求,就是给定一个查询的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搞一些事情的更多相关文章
- com.alibaba.druid.sql.parser.ParserException: syntax error, QUES %, pos 80 like报错解决
最近,把各应用的jdbc连接池统一从dbcp2改成了druid,运行时druid报sql解析错误,如下: select * from test where 1=1 &l ...
- 【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> ...
- ORA-00907: 缺失右括号问题或com.alibaba.druid.sql.parser.ParserException: TODO :IDENTIFIER的原因
以上只是说明错误的原因的一种.
- 利用 druid 的 sql parser 模块解析 sql 语句
druid 是阿里开源在 github 上面的数据库连接池,里面有一个专门解析 sql 语句的模块 源码位置: https://github.com/alibaba/druid SQL Parse ...
- Druid SQL注入防御模块技术浅析
官方参考: https://www.bookstack.cn/read/Druid/ffdd9118e6208531.md 前置知识 什么是Druid? Druid是一个高效的数据查询系统,主要解决的 ...
- Druid SQL 解析器概览
概览 Druid 的官方 wiki 对 SQL 解析器部分的讲解内容并不多,但虽然不多,也有利于完全没接触过 Druid 的人对 SQL 解析器有个初步的印象. 说到解析器,脑海里便很容易浮现 par ...
- sql注入搞事情(连载一)
SQL注入搞事情(连载一) 概述 写在最前面 为了有个合理的训练计划,山人准备长期开放自己的训练计划以及内容以供大家参考.山人专业是信息对抗技术,不是web方向的博客保证句句手打,如有问题请及时小窗. ...
- sql parser
最近在整理很多SQL代码, 需要分析出每个SQL的目标表和源表各有哪些, 网上没有找到工作具, 打算写个工具. Java调研结果:1. 商业组件包 sqlparser 有试用版组件, 限制SQL少于1 ...
- Spark SQL catalyst概述和SQL Parser的具体实现
之前已经对spark core做了较为深入的解读,在如今SQL大行其道的背景下,spark中的SQL不仅在离线batch处理中使用广泛,structured streamming的实现也严重依赖spa ...
随机推荐
- shell做成csv文件
echo a,b,c,d >aa.csv 其实就是用逗号做分隔符
- layui相关总结
表格操作实例1: https://sun_zoro.gitee.io/layuitableplug/testTableCheckboxDisabled?v0.1.9
- Access access中,查询字段是否存
'===========================================================' 过程及函数名: ListAllTableAndAllField' 版本号 ...
- jdk1.8-ArrayList源码分析
一:idea可以自动生成UML类图,ctrl+alt+u ArrayList类图 我没们看下类的继承关系 ) { ) { ) { )) )) newCapacity = minCapacity) ne ...
- Python爬虫学习==>第十二章:使用 Selenium 模拟浏览器抓取淘宝商品美食信息
学习目的: selenium目前版本已经到了3代目,你想加薪,就跟面试官扯这个,你赢了,工资就到位了,加上一个脚本的应用,结局你懂的 正式步骤 需求背景:抓取淘宝美食 Step1:流程分析 搜索关键字 ...
- 给Date的构造函数添加属性和方法
let d = Date.prototype; Object.defineProperties(d, { 'year': { get: function () { return this.getFul ...
- 【Windows】Windows server2008远程桌面只允许同时存在一个会话
打开控制面板-管理工具,终端服务-终端服务配置 1.连接:RDP-tcp 点右键,属性.网络适配器-最大连接数,只允许1个. 2.终端服务器授权模式:点右键,属性.常规,限制每个用户只能使用一个会话, ...
- sqlalchemy的常用字段
#encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,\ Float,Boolean,DECIMAL, ...
- Net 文件和流 I/O
文件和流 I/O 2017/03/30 文件和流 I/O(输入/输出)是指在存储媒介中传入或传出数据. 在 .NET Framework 中,System.IO 命名空间包含允许以异步方式和同步方式对 ...
- 搭建本地parcel仓库
参考:https://www.cloudera.com/documentation/enterprise/6/6.2/topics/cm_ig_create_local_parcel_repo.htm ...