hibernate中antlr对于hql与sql的转换源码的一些细节
Hibernate 5.1.11Final
关于hql中的对象类转换成表名。
在from模块里对hql抽象语法树进行匹配的时候,在path()规则会还原在对hql进行语法解析的时候生成的语法树。
public final String path(AST _t) throws RecognitionException {String p;AST path_AST_in = (_t == ASTNULL) ? null : (AST)_t;returnAST = null;ASTPair currentAST = new ASTPair();AST path_AST = null;AST a_AST = null;AST a = null;AST y_AST = null;AST y = null;p = "???";String x = "?x?";try { // for error handlingif (_t==null) _t=ASTNULL;switch ( _t.getType()) {case WEIRD_IDENT:case IDENT:{a = _t==ASTNULL ? null : (AST)_t;identifier(_t);_t = _retTree;a_AST = (AST)returnAST;astFactory.addASTChild(currentAST, returnAST);p = a.getText();path_AST = (AST)currentAST.root;break;}case DOT:{AST __t475 = _t;AST tmp7_AST = null;AST tmp7_AST_in = null;tmp7_AST = astFactory.create((AST)_t);tmp7_AST_in = (AST)_t;astFactory.addASTChild(currentAST, tmp7_AST);ASTPair __currentAST475 = currentAST.copy();currentAST.root = currentAST.child;currentAST.child = null;match(_t,DOT);_t = _t.getFirstChild();x=path(_t);_t = _retTree;astFactory.addASTChild(currentAST, returnAST);y = _t==ASTNULL ? null : (AST)_t;identifier(_t);_t = _retTree;y_AST = (AST)returnAST;astFactory.addASTChild(currentAST, returnAST);currentAST = __currentAST475;_t = __t475;_t = _t.getNextSibling();StringBuilder buf = new StringBuilder();buf.append(x).append(".").append(y.getText());p = buf.toString();path_AST = (AST)currentAST.root;break;}default:{throw new NoViableAltException(_t);}}}catch (RecognitionException ex) {reportError(ex);if (_t!=null) {_t = _t.getNextSibling();}}returnAST = path_AST;_retTree = _t;return p;
}
在此处,当没有匹配到点’.’的时候,也就是匹配到的是常量的时候会直接返回牡丹石如果匹配到的点,那么需要对当前的子树进行中序遍历,还原此处的类名全称,在此处匹配完点之后会继续通过path()规则去匹配其子节点,达到递归中序遍历该子树的目的。
相应的,不断匹配点,直到匹配到字符串常量x的时候,会紧接着得到当前字符串的兄弟节点字符串为y,当前子树的字符串凭借为x.y,之后不断向前拼接字符串,最后可以平成为完整的类。
在得到完整的类路径之后,会在from的规则fromElement()方法下createFromElement()方法中根据类名获得对应的tableName,也就是表名。
关于嵌套的处理
在sql语句常常存在嵌套的存在,在HqlSqlWalker给出了解决的方案。
以from模块为例子,在sql的抽象语法树中,每一个from子树都会有一个fromClause作为其父节点,每个fromClause都存在一个level属性代表其代表第几层嵌套。
同时在HqlSqlBaseWalker中给出了一个堆栈来存放当前所正在解析的fromClause节点,每次在准备进行一轮新的from解析的时候都会将当前fromClause节点入栈,结束之后出栈,达到迅速获得当前fromClause上下文的目的。同时,也在fromClause中选择一个set来存放其子from模块。
关于hql节点与sql节点的转换
Hql节点的生成以词法解析的结果得到的Token为依据来产生对应的语法树节点。
public AST create(Token var1) {AST var2 = this.create(var1.getType());if (var2 != null) {var2.initialize(var1);}return var2;
}
sql节点的生成以hql语法树节点的类型(int值)为依据,来产生对应的sql语法树节点。
public AST create(AST var1) {if (var1 == null) {return null;} else {AST var2 = this.create(var1.getType());if (var2 != null) {var2.initialize(var1);}return var2;}
}
由此可以达到hql节点与sql节点的同样语意的转换。
关于hql赋值参数的语句
Hql中赋值支持冒号加变量名,当在转换过程中匹配表达式的时候匹配到了冒号或者问号,则会开始参数的匹配,如果存在冒号或者带数字的问号,则会作为带名称的参数加入到语法树中,而单纯的问号只是作为普通的参数节点加入的语法树中。
protected AST generateNamedParameter(AST delimiterNode, AST nameNode) throws SemanticException {return (AST)astFactory.make( (new ASTArray(1)).add(astFactory.create(NAMED_PARAM,nameNode.getText())));
}protected AST generatePositionalParameter(AST inputNode) throws SemanticException {return (AST)astFactory.make( (new ASTArray(1)).add(astFactory.create(PARAM,"?")));
}
hibernate中antlr对于hql与sql的转换源码的一些细节相关推荐
- hibernate中antlr对于hql生成抽象语法树源码解析
Hibernate版本5.1.11FInal 以一句update语句作为例子. update com.tydhot.eninty.User set userName=:userName where u ...
- hibernate中antlr对于hql的词法分析源码解析
Hibernate版本 5.1.11 private HqlParser parse(boolean filter) throws TokenStreamException, RecognitionE ...
- HQL语句中数据类型转换,及hibernate中createQuery执行hql报错
一.HQL语句中数据类型转换: 我们需要从数据库中取出序号最大的记录,想到的方法就是使用order by子句进行排序(desc倒序),然后取出第一个对象,可是当初设计数据库时(我们是在原来的数据库的基 ...
- sql注入——php源码的审计(以sql-lab 1~15为例)(超详细)
sql注入--php源码的审计(以sql-lab 1~15为例)(超详细) sql注入 sql注入:web应用对用户输入数据的合法性没有判断,并且传入的参数是攻击者可控的,因此攻击者通过构造不同的sq ...
- 淘宝数据库OceanBase SQL编译器部分 源码阅读--生成物理查询计划
淘宝数据库OceanBase SQL编译器部分 源码阅读--生成物理查询计划 SQL编译解析三部曲分为:构建语法树,制定逻辑计划,生成物理执行计划.前两个步骤请参见我的博客<<淘宝数据库O ...
- java计算机毕业设计ssm中药城药材销售管理系统eah41(附源码、数据库)
java计算机毕业设计ssm中药城药材销售管理系统eah41(附源码.数据库) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行 ...
- java中的string函数_java中string.trim()函数的作用实例及源码
trim()的作用:去掉字符串首尾的空格. public static void main(String arg[]){ String a=" hello world "; Str ...
- python学习-综合练习三(斐波那契数列、阿姆斯特朗数、//和/、十进制转二进制bin、八进制oct、十六进制hex、进制转换源码、python中::和:的区别)
文章目录 斐波那契数列 阿姆斯特朗数 十进制转二进制bin.八进制oct.十六进制hex 补充进制转换源码 python中::和:的区别 说明:本篇博文的知识点大部分来自 Python3 实例 斐波那 ...
- Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析
Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析 生鲜电商搜索引擎的特点 众所周知,标准的搜索引擎主要分成三个大的部分,第一步是爬虫系统,第二步是数据分析,第三步才 ...
最新文章
- 程序设计分析(开篇)——混沌初开,顿悟设计
- 运营书籍:新媒体运营实战笔记
- matlab dsp工具箱_GPU中的并行运算,加速你的Matlab程序
- 【错误记录】VMware 虚拟机报错 ( 向 VMWare 虚拟机中的 Ubuntu 系统拷贝文件时磁盘空间不足 )
- python学习day-8 迭代器 生成器 装饰器
- android消息机制
- VTK:Rendering之PhysicalBasedRendering
- 【机器视觉】Qt联合Halcon编程之显示多图片
- 常见形式 Web API 的简单分类总结
- 使用率激增 250%,这份报告再次将 Serverless 推向幕前
- postman并发测试_PostMan接口压力测试
- 小米发布了10款可以免费商用的字体MiSans字体(含下载地址)
- vmware虚拟机使用教程
- 有计算机测试你几岁,How-Old刷屏了吧!测测你看起来几岁?
- 中国联通物联网平台能力介绍
- 欧姆龙SYSMAC STUDIO如何与基恩士DL-EP1进行EIP通信
- php电子杂志,Phpwind推电子杂志《站长天下》 网罗站长故事
- 小飞鱼 通达OA二次开发网络课程 系列视频课程在CSDN发布
- android studio复选按钮样式_Android 自定义CheckBoxPreference的CheckBox复选框
- mysql foreign key references_使用带有和不带有FOREIGN KEY的REFERENCES之间的区别?