<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  回復  更多評論
      

    主站蜘蛛池模板: 中文字幕免费观看全部电影| 亚洲av日韩综合一区二区三区| 精品国产免费人成网站| 日本免费人成黄页网观看视频| 中文字幕亚洲情99在线| 在线看片免费不卡人成视频| 亚洲最大免费视频网| 成人免费视频网站www| 亚洲人精品亚洲人成在线| 好爽…又高潮了毛片免费看 | 国产成人精品免费视频大全五级| 亚洲精品无码久久久久YW| 国产精品va无码免费麻豆| 久久综合亚洲色hezyo| 亚洲人成无码久久电影网站| 一级毛片大全免费播放下载| 亚洲女久久久噜噜噜熟女| 91精品国产免费| 中文字幕亚洲码在线| 亚洲A∨精品一区二区三区| 中国内地毛片免费高清| 久久久久亚洲av无码专区喷水| 91精品免费在线观看| 亚洲av乱码中文一区二区三区| 亚洲国产精品嫩草影院久久| 99视频在线观看免费| 亚洲国产美女在线观看| 国产免费av一区二区三区| 三级网站在线免费观看| 亚洲美女在线观看播放| 国产精品麻豆免费版| 国产午夜精品久久久久免费视| 亚洲色欲或者高潮影院| 日本19禁啪啪无遮挡免费动图| 中文字幕成人免费高清在线| 亚洲午夜一区二区电影院| 亚洲?v女人的天堂在线观看| 免费A级毛片av无码| 偷自拍亚洲视频在线观看| 久久久无码精品亚洲日韩蜜桃| 成年女人免费视频播放77777 |