`
rq2_79
  • 浏览: 240445 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

hibernate 的HQL源码分析

阅读更多
一、HQL代码的构建。
(1)首先将hibernate中的src目录下的代码解压。
(2)安装配置好antlr。
(3) 把grammar目录下的三个.g文件(hql.g,hql-sql.g,sql-gen.g)解压到一个目录,然后从命令行进入此目录,依次运行 "java antlr.Tool hql.g","java antlr.Tool hql-sql.g","java antlr.Tool sql-gen.g",将生成的java代码拷贝到源代码的org.hibernate.hql.antlr下。
二、让我们从 QueryTranslatorImpl开始分析,当调用session.find('...')的时候将会调用QueryTranslatorImpl 的compile方法来解析hql语句为sql语句。compile则主要是调用的doCompile方法。
// PHASE 1 : Parse the HQL into an AST.
HqlParser parser = parse( true );

// PHASE 2 : Analyze the HQL AST, and produce an SQL AST.
HqlSqlWalker w = analyze( parser, collectionRole );
sqlAst = ( Statement ) w.getAST();
generate( ( QueryNode ) sqlAst );
queryLoader = new QueryLoader( this, factory, w.getSelectClause() );

parse的主要代码:
private HqlParser parse(boolean filter)
 HqlParser parser = HqlParser.getInstance( hql );
 parser.statement();
 AST hqlAst = parser.getAST();
  return parser;
}
analyze的主要代码:
private HqlSqlWalker analyze(HqlParser parser, String collectionRole) throws QueryException, RecognitionException {
 HqlSqlWalker w = new HqlSqlWalker( this, factory, parser, tokenReplacements, collectionRole );
 AST hqlAst = parser.getAST();
 w.statement( hqlAst );
 return w;
}
generate的主要代码:
private void generate(AST sqlAst) throws QueryException, RecognitionException {
 SqlGenerator gen = new SqlGenerator(factory);
 gen.statement( sqlAst );
 sql = gen.getSQL();
}

可以看到主要是三步:调用parse方法将hql解析成AST,调用analyze根据上一步生成的AST生成SQLAST,调用generate根据上一步生成的SQL AST生成sql语句, 调用w.getSelectClause()就得到sql语句了。
“用parser把ast抽取出来,再用treeparser进行动作的double pass builder模式,解耦了parser和generation,再配合template,是antlr推荐的最佳模式。”-《看Hibernate3如何解释HQL语言》
1、三个语法文件的作用:

hibernate的hql grammar文件一共有三个,在/grammar目录下:
   1.hql.g   定义token类和parser类,将hql解释成hql的抽象语法树(ast)
   2.hql-sql.g  定义tree walker ,将hql ast转化为sql ast,将生成模块与hibernate解耦。
   3.sql-gen.g 定义tree walker,从sql ast生成sql
”-《看Hibernate3如何解释HQL语言》
2、
逐步分析:
(1)parse方法:
HqlParser是从hql.g生成的HqlBaseParser继承来的,主要实现了HqlBaseParser定义的几个模版方法,传入的是hql语句,传出的是HQL AST。
(2)analyze:
HqlSqlWalker 是从hql-sql.g生成的HqlSqlBaseWalker继承来的,HqlSqlBaseWalker又是从TreeParser继承的,主要实现 了HqlSqlBaseWalker定义的几个模版方法,传入的是HQL AST,传出的是SQL AST。
hql-sql.g比hql.g简单许多了,因为hql-sql.g已经为我们生成了HQL AST了,hql-sql.g需要做的就是把HQL AST组装成强类型的SQL AST,此处大量引用了hql.g中定义的Vocabulary。
比如:
query!
 : #( QUERY { beforeStatement( "select", SELECT ); }
   // The first phase places the FROM first to make processing the SELECT simpler.
   #(SELECT_FROM
    f:fromClause
    (s:selectClause)?
   )
   (w:whereClause)?
   (g:groupClause)?
   (o:orderClause)?
  ) {
  // Antlr note: #x_in refers to the input AST, #x refers to the output AST
  #query = #([SELECT,"SELECT"], #s, #f, #w, #g, #o);
  beforeStatementCompletion( "select" );
  processQuery( #s, #query );
  afterStatementCompletion( "select" );
 }
 ;
这里主要就是在调用模版方法拼状强类型的SQL AST(异构AST)。所有的节点都定义在org.hibernate.hql.ast.tree中。
与第一部的HqlParser用户几乎不用写任何代码相反,我们需要完成我们从HqlSqlBaseWalker继承来的HqlSqlWalker的那些模版方法。
(3)generate方法:
遍历SQL AST,输出sql语句。SqlGenerator是从sql-gen.g生成的SqlGeneratorBase继承来的。输入的是SQL AST,输出的是SQL语句。我个人认为这一步也可以通过全部书写代码完成,可能更清晰,更灵活。
selectExpr
 : e:selectAtom { out(e); }
 | count
 | #(CONSTRUCTOR (DOT | IDENT) ( selectColumn )+ )
 | methodCall
 | aggregate
 | c:constant { out(c); }
 | arithmeticExpr
 | PARAM { out("?"); }
 | sn:SQL_NODE { out(sn); }
 | { out("("); } selectStatement { out(")"); }
其中的out("(");就是在拼装代码。
分享到:
评论
1 楼 chenfei3306 2011-09-08  
感谢楼主的分析,现在对hql的解析有了大体的认识了

相关推荐

    HibernateHql综合测试小程序

    《Hibernate HQL综合测试小程序详解》 在Java开发领域,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了...在实际工作中,结合源码分析,可以进一步优化和定制查询逻辑,满足复杂业务场景的需求。

    hibernate源码分析过程

    Hibernate 源码分析过程 Hibernate 是一个基于 Java 的 ORM(Object-Relation Mapping)框架,允许开发者使用面向对象的方式与关系数据库交互。在本文中,我们将对 Hibernate 的源码进行深入分析,并探讨其核心特性...

    Hibernate源码解析(三)

    在阅读《Hibernate源码解析(三)》的过程中,配合hibernate源码分析(三).docx文档,读者可以更直观地理解这些概念,并可能涉及具体的类和方法,如`Query`、`SessionFactoryBuilder`、`EntityPersister`等。...

    Hibernate源码解析(一)

    - 错误排查:当遇到问题时,源码分析能更准确地定位问题所在,提高解决问题的效率。 - 自定义扩展:熟悉源码后,我们可以根据需求自定义拦截器、事件监听器等,实现特定功能。 总结来说,Hibernate源码解析是一个...

    hibernate源码分析

    **Hibernate源码分析** Hibernate,一个著名的开源Java对象关系映射(ORM)框架,通过将Java对象和数据库表之间的映射关系自动化,极大地简化了数据访问层的开发工作。本篇将深入探讨Hibernate的源码,揭示其执行...

    Spring,Hibernate整合源码

    源码分析通常涉及对配置文件的理解,如Spring的beans.xml和Hibernate的hibernate.cfg.xml,以及相关类的设计和交互。此外,还可以通过源码学习到如何处理异常、优化数据库操作,以及如何设计符合松耦合原则的架构。

    hibernate-3.5.6 源码

    通过分析Hibernate 3.5.6的源码,开发者可以了解到其内部的事务处理、查询优化、缓存策略等实现细节,这对于提升Java数据库编程技能,或者进行ORM框架的二次开发具有重要意义。这个源码库是一个宝贵的教育资源,可以...

    hibernate_3.1源码

    源码分析是理解其工作原理、学习设计模式以及提升Java开发技能的重要途径。尽管初学者可能在面对源码时感到困惑,但深入研究会带来巨大的收获。 标题"hibernate_3.1源码"指出了我们关注的是Hibernate的3.1版本。这...

    hibernate框架源码

    源码分析是理解任何软件系统工作原理的关键,对于Hibernate也不例外。当你下载并解压"hibernate框架源码",你将有机会深入到Hibernate的核心机制中,了解其实现的细节。例如,你可以看到Hibernate如何通过Session...

    hibernate3.6.1源码

    源码分析: 1. **对象关系映射(ORM)**:Hibernate的核心功能是实现ORM,它将Java类映射到数据库表,对象的属性对应于表的列。在Hibernate 3.6.1中,这一映射主要通过`hibernate.cfg.xml`配置文件和`.hbm.xml`映射...

    hibernate源码

    总之,Hibernate源码的分析和学习可以帮助Java开发者提升数据库编程的效率,更好地理解和利用ORM框架。这个`hibernate-release-4.1.4.Final`版本的源码和jar包,是学习和研究Hibernate的理想资源。

    hibernate 3.3 源码

    Hibernate 3.3 是一个历史悠久但仍然非常重要的Java持久化框架,它允许开发人员通过对象关系映射(ORM)技术将数据库操作与业务对象无缝...此外,源码分析还能帮助开发者解决实际项目中的问题,提高代码质量和性能。

    hibernate,hibernate实例源码

    源码分析是深入理解Hibernate工作原理的关键。通过阅读和理解以下关键组件的源码: 1. Configuration:配置加载和解析的过程。 2. SessionFactory:如何根据配置信息创建SessionFactory,以及其内部的缓存机制。 3....

    hibernate4.22源码

    对于深入理解Hibernate的工作原理,分析其源码是至关重要的。`hibernate4.2.21.Final`是Hibernate 4.2系列的一个稳定版本,下面将对这个版本中的关键知识点进行详细解释。 1. **实体管理**:Hibernate的核心功能之...

    hibernate-3.2源码包

    8. **HQL(Hibernate Query Language)**:Hibernate特有的查询语言,类似于SQL,但针对对象模型设计,用于执行复杂的对象查询。 9. **第二级缓存(Second-Level Cache)**:Hibernate 支持二级缓存,能提高数据...

    精通hibernate源码ch5

    七、源码分析 深入到源码层面,我们可以看到Hibernate如何将Java对象转化为SQL语句,以及如何执行这些SQL语句并处理结果。这包括了Hibernate的CriteriaBuilder、QueryExecutor、EntityPersister等关键组件的工作...

    Hibernate源码

    Hibernate源码分析有助于深入理解其内部机制,提高开发效率,优化数据库操作性能。 1. **Hibernate核心模块(hibernate-core)** Hibernate的核心模块包含了ORM框架的主要功能,如实体管理、查询语言(HQL)、事件...

    hibernate源码分析一_启动过程_

    **hibernate源码分析:启动过程** 在深入探讨Hibernate启动过程之前,首先需要了解Hibernate是什么。Hibernate是一个开源的对象关系映射(ORM)框架,它为Java开发人员提供了一种在Java应用程序中操作数据库的方式...

    传智播客hibernate源码

    - `Jpa_0914`: JPA(Java Persistence API)是Java平台上的ORM规范,与Hibernate有关,可能包含JPA的实现示例或与Hibernate的对比分析。 - `hibernate_080914`: 直接与Hibernate相关的源码或教程材料,可能涵盖...

Global site tag (gtag.js) - Google Analytics