<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欧美国产在钱| 少妇无码一区二区三区免费| 国产卡一卡二卡三免费入口| 久久久久亚洲精品男人的天堂 | 免费v片视频在线观看视频| 亚洲国产精品无码一线岛国| 亚洲中文无码永久免| 免费精品99久久国产综合精品| 国产男女猛烈无遮挡免费视频网站 | 中文字幕在线免费播放| 日韩成全视频观看免费观看高清| 国产亚洲一区二区三区在线观看| 爱情岛论坛亚洲品质自拍视频网站| 中文字幕免费视频一| 亚洲伊人久久精品影院| 亚洲AV香蕉一区区二区三区| 亚洲免费人成视频观看| 国产日韩亚洲大尺度高清| 国内精品免费在线观看| 亚洲欧洲日本精品| 午夜精品免费在线观看| 亚洲国产高清美女在线观看| 成人男女网18免费视频| 亚洲H在线播放在线观看H| 日韩内射激情视频在线播放免费 | 亚洲一区二区无码偷拍| 成人伊人亚洲人综合网站222| 亚洲一卡2卡4卡5卡6卡残暴在线| 最近中文字幕mv手机免费高清| 久久久亚洲精华液精华液精华液| 亚洲精品无码永久在线观看| 看成年女人免费午夜视频| 日本高清免费aaaaa大片视频| 全部一级一级毛片免费看| 五月天婷亚洲天综合网精品偷| 国产无限免费观看黄网站| 亚洲中文字幕无码久久综合网| 五月婷婷免费视频| 国外亚洲成AV人片在线观看| 19禁啪啪无遮挡免费网站|