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

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

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

    每日一得

    不求多得,只求一得 about java,hibernate,spring,design,database,Ror,ruby,快速開發
    最近關心的內容:SSH,seam,flex,敏捷,TDD
    本站的官方站點是:顛覆軟件

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      220 隨筆 :: 9 文章 :: 421 評論 :: 0 Trackbacks
    越來越發現其實掌握 hibernate并不容易,Spring用起來其實簡單多了,但是在用hibernate的時候真的是需要一定的時間積累,對一個項目組來說如果采用hibernate最好有一個對hibernate比較清楚的人否則碰到問題就會成為項目的風險。
    我想告訴各位的是,掌握hibernate可能比你預期的難多了,當你輕松的告訴我,hibernate很簡單的時候該是你自己多反省了. (只有一種情況例外,你是一個牛人)

    好了,一個引子廢話那么多,其實今天只是想先說一說hibernate里的Fetch的作用.

    大家都知道,在hibernate里為了性能考慮,引進了lazy的概念,這里我們以Parent和Child為模型來說明,

    public?class?Parent?implements?Serializable?{

    ????
    /**?identifier?field?*/
    ????
    private?Long?id;

    ????
    /**?persistent?field?*/
    ????
    private?List?childs;

    ????
    //skip?all?getter/setter?method

    ??
    }??



    public?class?Child?implements?Serializable?{

    ????
    /**?identifier?field?*/
    ????
    private?Long?id;

    ????
    /**?persistent?field?*/
    ????
    private?net.foxlog.model.Parent?parent;

    ??? //skip all getter/setter method

    }

    在我們查詢Parent對象的時候,默認只有Parent的內容,并不包含childs的信息,如果在Parent.hbm.xml里設置lazy="false"的話才同時取出關聯的所有childs內容.

    問題是我既想要hibernate默認的性能又想要臨時的靈活性該怎么辦?? 這就是fetch的功能。我們可以把fetch與lazy="true"的關系類比為事務當中的編程式事務與聲明式事務,不太準確,但是大概是這個意思。

    總值,fetch就是在代碼這一層給你一個主動抓取得機會.

    Parent?parent?=?(Parent)hibernateTemplate.execute(new?HibernateCallback()?{
    ????????????
    public?Object?doInHibernate(Session?session)?throws?HibernateException,?SQLException?{
    ????????????????Query?q?
    =?session.createQuery(
    ????????????????????????
    "from?Parent?as?parent?"+
    ????????????????????????????????
    "?left?outer?join?fetch?parent.childs?"?+
    ????????????????????????????????
    "?where?parent.id?=?:id"
    ????????????????);
    ????????????????q.setParameter(
    "id",new?Long(15));
    ????????????????
    return?(Parent)q.uniqueResult();
    ????????????}

    ????????});

    ????????Assert.assertTrue(parent.getChilds().size()?
    >?0);


    你可以在lazy="true"的情況下把fetch去掉,就會報異常. 當然,如果lazy="false"就不需要fetch了


    有一個問題,使用Fetch會有重復記錄的現象發生,我們可以理解為Fetch實際上不是為Parent服務的,而是為Child服務的.所以直接取Parent會有不匹配的問題.



    參考一下下面的這篇文章
    Hibernate集合初始化

    ======================================================================

    update:以上有些結論錯誤,實際上在hibernate3.2.1版本下測試,可以不出現重復記錄,

    public?void?testNPlusOne()?throws?Exception{
    ????????List?list?
    =?(List)hibernateTemplate.execute(new?HibernateCallback()?{
    ????????????
    public?Object?doInHibernate(Session?session)?throws?HibernateException,?SQLException?{
    ????????????????Query?q?
    =?session.createQuery(
    ????????????????????????
    "select?distinct?p?from?net.foxlog.model.Parent?p?inner?join?fetch?p.childs"
    ????????????????);
    ????????????????
    return?q.list();
    ????????????}

    ????????});

    ????????
    //((Parent)(list.get(0))).getChilds();
    ????????System.out.println("list?size?=?"?+?list.size());
    ????????
    for(int?i=0;i<list.size();i++){
    ????????????Parent?p?
    =?(Parent)list.get(i);
    ????????????System.out.println(
    "===parent?=?"?+?p);
    ????????????System.out.println(
    "===parent's?child's?length?=?"?+?p.getChilds().size());
    ????????}

    ????}


    打印結果如下:
    Hibernate:?select?distinct?parent0_.id?as?id2_0_,?childs1_.id?as?id0_1_,?childs1_.parent_id?as?parent2_0_1_,?childs1_.parent_id?as?parent2_0__,?childs1_.id?as?id0__?from?parent?parent0_?inner?join?child?childs1_?on?parent0_.id=childs1_.parent_id
    list?size?
    =?3
    ===parent?=?net.foxlog.model.Parent@1401d28[id=14]
    ===parent's?child's?length?=?1
    ===parent?=?net.foxlog.model.Parent@14e0e90[id=15]
    ===parent's?child's?length?=?2
    ===parent?=?net.foxlog.model.Parent@62610b[id=17]
    ===parent's?child's?length?=?3

    另外,如果用open session in view模式的話一般不用fetch,但首先推薦fetch,如果非用的話因為有N+1的現象,所以可以結合batch模式來改善下性能.


    posted on 2006-12-01 13:01 Alex 閱讀(19372) 評論(7)  編輯  收藏 所屬分類: Hibernate

    評論

    # re: Hibernate的Fetch 2006-12-01 16:39 loocky
    并不是HIbernate難用而是對數據庫原理的理解不夠,Hibernate是一個很好的工具  回復  更多評論
      

    # re: Hibernate的Fetch 2006-12-01 17:42 野風
    你可以IBATIS,這個hibernate學習成本要底一些,而且也比較容易掌握,在批量處理的時候效率也比hibernate高很多  回復  更多評論
      

    # re: Hibernate的Fetch 2007-08-27 17:19 楊愛友
    我按照你的思路去試驗,一個parent表,有一條記錄,對應有三個child,當我執行Query q = session.createQuery(
    "select distinct p from Parent p inner join fetch p.childs"
    );
    查詢時仍然出現重復記錄現象,打印出的hql語句看到distinct也起作用了啊
    不解中,如果你有習慣用QQ的話,請加我一下54305792,想你請教一下。  回復  更多評論
      

    # re: Hibernate的Fetch 2008-06-03 15:57 beyondlife
    這是因為他用的集合是List而不是Set

    @楊愛友
      回復  更多評論
      

    # re: Hibernate的Fetch 2008-06-03 16:01 beyondlife
    不要老拿什么數據庫原理的東西來嚇唬了,不會數據庫原理還用HIBERNATE,實際應用中不可能不碰到問題.
    @loocky
      回復  更多評論
      

    # re: Hibernate的Fetch[未登錄] 2008-06-04 17:29 javaboy
    sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos sos

    select distinct m from Module as m join fetch m.functions as f join f.roles as r join r.users as u where u.id=? and m.menu='1' and f.menu='1' and m.status='1' and f.status='1' order by m.orderNo

    加了 fetch 后就不能去掉重復和記錄了 hiberante 的版本是3.2  回復  更多評論
      

    # re: Hibernate的Fetch[未登錄] 2008-06-04 18:26 javaboy
    @javaboy

    我的版本是 3.25ga  回復  更多評論
      

    主站蜘蛛池模板: 亚洲精品中文字幕无乱码麻豆 | 97视频免费在线| 亚洲精品无码MV在线观看| a免费毛片在线播放| 亚洲午夜精品第一区二区8050| 春暖花开亚洲性无区一区二区| 国产高清免费在线| 国产精品亚洲一区二区三区| 国产免费观看青青草原网站| 亚洲日韩中文字幕无码一区| 真实乱视频国产免费观看| 亚洲AV色无码乱码在线观看| 日韩精品视频免费网址| 美女被羞羞网站免费下载| 夜色阁亚洲一区二区三区| 视频一区在线免费观看| 亚洲精品人成无码中文毛片| 国产一级婬片A视频免费观看| 亚洲阿v天堂在线| 妻子5免费完整高清电视| 亚洲精品无码aⅴ中文字幕蜜桃| 四虎成人精品在永久免费| caoporm超免费公开视频| 亚洲高清在线观看| 国产免费AV片在线播放唯爱网| 亚洲私人无码综合久久网| 亚洲国产精品综合久久一线| a级毛片免费全部播放无码| 亚洲成年人免费网站| 麻豆国产VA免费精品高清在线 | 亚洲色欲色欲www在线播放| 国产yw855.c免费视频| 99久久精品毛片免费播放| 久久亚洲精品成人无码网站| 日韩视频免费在线| 国内精品免费在线观看| 亚洲熟妇AV日韩熟妇在线| 精品国产综合成人亚洲区| 永久免费毛片在线播放| 两个人日本WWW免费版| 亚洲第一成人在线|