<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    如鵬網 大學生計算機學習社區

    CowNew開源團隊

    http://www.cownew.com 郵件請聯系 about521 at 163.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      363 隨筆 :: 2 文章 :: 808 評論 :: 0 Trackbacks

    作者楊中科

    CowNew 開源團隊網站 http://www.cownew.com

    論壇 http://www.cownew.com/newpeng/?

    轉載請保留此信息

    一、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("(");就是在拼裝代碼。

    posted on 2006-06-02 00:56 CowNew開源團隊 閱讀(4975) 評論(2)  編輯  收藏

    評論

    # re: CowNew開源學習文檔-hibernate 的HQL源碼分析1 2006-06-02 10:03 人要有夢想
    其實說白了就是使用antlr做詞法語法分析。
    HQL->HQL AST->SQL AST->SQL  回復  更多評論
      

    # re: CowNew開源學習文檔-hibernate 的HQL源碼分析1 2007-06-29 09:56 大灰狼
    小弟請教一個問題: 在oracle中有一個NUMBER(2)字段,里面有一個記錄存有值2;現寫一個hql語句,.....where typelevel=2或typelevel<>2為什么都不起作用,要不該怎么寫?  回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产精品永久免费| 亚洲国产午夜精品理论片 | 久久国产免费福利永久| 亚洲熟女少妇一区二区| 本免费AV无码专区一区| 亚洲精品无码永久在线观看你懂的| 特级做a爰片毛片免费看| 亚洲福利视频一区二区| 一级大黄美女免费播放| 久久亚洲中文字幕精品一区四| jizz免费一区二区三区| 亚洲精品国产品国语在线| 国产一级a毛一级a看免费人娇 | 亚洲激情视频在线观看| 99久久免费观看| 成人区精品一区二区不卡亚洲| 国外成人免费高清激情视频| 99亚洲精品卡2卡三卡4卡2卡| 亚洲av无码专区在线观看素人| 一级做a爰片久久毛片免费陪| 久久精品国产亚洲AV不卡| 中文字幕免费在线观看动作大片| 亚洲av午夜福利精品一区| 午夜福利不卡片在线播放免费| 一本色道久久88亚洲精品综合 | 永久看日本大片免费35分钟| 中文字幕亚洲精品无码| 国产人成免费视频| 免费污视频在线观看| 亚洲a级在线观看| 亚洲 自拍 另类小说综合图区| 青青操免费在线观看| 亚洲国产日韩在线| 免费人成网站在线高清| 毛片免费在线观看| 亚洲av无码久久忘忧草| 亚洲一区二区视频在线观看| 久久精品无码专区免费东京热| 亚洲国产成人AV在线播放| 国产精品久久久亚洲| 午夜爱爱免费视频|