<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開源團隊 閱讀(4978) 評論(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為什么都不起作用,要不該怎么寫?  回復  更多評論
      


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


    網站導航:
     
    主站蜘蛛池模板: 久久国产高潮流白浆免费观看| 免费看美女午夜大片| 在线涩涩免费观看国产精品 | 免费亚洲视频在线观看| 又爽又高潮的BB视频免费看| 国产亚洲玖玖玖在线观看| 国产美女在线精品免费观看| 国产成人亚洲合集青青草原精品| 无码av免费毛片一区二区| 精品亚洲AV无码一区二区三区| 手机在线免费视频| 亚洲国产精品ⅴa在线观看| 巨胸狂喷奶水视频www网站免费| 国产成人99久久亚洲综合精品| 久久九九免费高清视频| 成人片黄网站A毛片免费| 亚洲欧美熟妇综合久久久久| 日韩免费观看的一级毛片| 亚洲人成在线观看| 国产免费不卡v片在线观看| 国产亚洲日韩在线三区| 免费国产成人午夜在线观看| 亚洲国产精品久久久久秋霞影院| 亚洲人成www在线播放| 日韩免费视频在线观看| 亚洲免费一区二区| 亚洲高清在线mv| 四虎影视免费在线| 中文字幕免费在线看线人动作大片 | ssswww日本免费网站片| 国产gav成人免费播放视频| 黄桃AV无码免费一区二区三区| 亚洲AV无码久久精品蜜桃| 成人免费无码视频在线网站| 国产成人高清亚洲一区91| 亚洲国产成人片在线观看无码| 亚洲AV无码男人的天堂| 中文字幕人成无码免费视频| 美景之屋4在线未删减免费| 韩国18福利视频免费观看| 亚洲综合色丁香麻豆|