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

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

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

    單一數據加載:Session.get/load
    均可以根據指定的實體類和id從數據庫中讀取記錄,并返回與之對應的實體對象。
    區別:
    1.如果未能發現符合條件的記錄,get方法返回null,而load方法會拋出一個ObjectNotFoundException。
    2.Load方法可返回實體的代理類實例,而get方法永遠直接返回實體類。
    3.load方法可以充分利用內部緩存和二級緩存中的現有數據,而get方法僅在內部緩存中查找,如果沒有發現對應的數據,將越過二級緩存,直接調用SQL完成數據讀取。
    數據加載的過程:
    1.在一級緩存中,根據實體類型和id進行查找,如果在第一級緩存中命中,且數據狀態合法,則直接返回。
    2.Session會在當前"NonExists"記錄中進行查找,如果在"NonExists"記錄中存在同樣的條件,返回null。
    3.對load方法而言,如果內部緩存中沒法現有效數據,查詢二級緩存,命中則返回。
    4.如果緩存中無有效數據,發起數據庫查詢操作(Select SQL),如果經過查詢未發現對應記錄,將此次查詢的信息在"NonExists"中加以記錄,返回null.
    5.根據映射配置和Select SQL查詢得到的ResultSet,創建對應的數據對象。
    6.將對象納入一級緩存。
    7.執行Interceptor.onLoad方法(如果有對應的Interceptor)
    8.將數據納入二級緩存
    9.如果數據對象實現了LifeCycle接口,則調用數據對象的onLoad方法。
    10.返回數據對象。


    批量查詢:Session.find/iterate
    查詢性能往往是系統性能表現的一個重要方面,查詢機制的優劣很大程度上決定了系統的整體性能。這個領域往往也存在最大的性能調整空間。

    hibernate2中Session.find()對應于3中的session.createQuery().list();
    hibernate2中Session.iterate()對應于3中的session.createQuery().iterate();
    find和iterate區別:
    find方法通過一條Select SQL實現了查詢操作,而iterate方法要執行多條Select SQL.
    iterate第一次查詢獲取所有符合條件的記錄的id,然后再根據各個id從庫表中讀取對應的記錄,這是一個典型的N+1次的查詢問題,如果符合條件記錄有10000條,就需要執行10001條Select SQL,可想性能會如何的差。

    那為什么要提供iterator方法,而不只是提供高效率的find方法?

    原因1.與hibernate緩存機制密切相關
    find方法實際上是無法利用緩存的,它對緩存只寫不讀。
    find方法只執行一次SQL查詢,它無法判斷緩存中什么樣的數據是符合條件的,也無法保證查詢結果的完整性。而iterate方法,會首先查詢所有符合條件記錄的id,然后根據id去緩存中找,如果緩存中有該id,就返回,沒有可以根據id再去數據庫查詢。
    String hql = "from TUser where age > ?";
    List userList = session.find(hql, new Integer(18), Hibernate.INTEGER);
    Iterator it = session.iterate(hql, new Integer(18), Hibernate.INTEGER);
    順序執行,iterate方法只會執行一次SQL查詢,就是查找id,然后根據id就可以從緩存中獲得數據。

    String hql = "from TUser where age > ?";
    List userList = session.find(hql, new Integer(18), Hibernate.INTEGER);
    userList = session.find(hql, new Integer(18), Hibernate.INTEGER);
    緩存是不起作用的。
    如果目標數據讀取相對較為頻繁,通過iterate這種機制,會減少性能損耗。

    原因2.內存使用上的考慮
    find方法將一次獲得的所有記錄并將其讀入內存。如果數據量太大,可能會觸發OutOfMemoryError,從而導致系統異常。解決方案之一就是結合iterate方法和evict方法逐條對記錄進行處理,將內存消化保持在一個可以接受的范圍之內。如:
    String hql = "from TUser where age > ?";
    Iterator it = session.iterate(hql, new Integer(18), Hibernate.INTEGER);
    while(it.hasNext()) {
    ??? TUser user = (TUser)it.next();
    ???
    ??? //將對象從一級緩存中刪除
    ??? session.evict(user);

    ??? //二級緩存可以設定最大緩存量,達到后自動對較老數據進行廢除,但也可以通過編
    ??? //碼移除,這樣有助于保持數據有效性。
    ??? sessionFactory.evict(TUser.class, user.getID());
    }


    批量數據處理的緩存同步問題
    1.hibernate 2:
    session.delete("from TUser");
    會先查詢出id,然后逐個id執行 delete from T_User where id = ?;
    這樣造成效率低下。
    為什么不直接采用一條Delete SQL?是因為ORM要自動維持其內部狀態屬性,必須知道用戶作了什么操作。必須先從數據庫中獲得待刪除對象,然后根據這些對象對內部緩存和二級緩存的數據進行整理,以保持內存狀態與數據庫的一致性。
    單執行一條刪除語句,刪除了什么數據,只有數據庫知道,ORM無法得知。下次用戶從緩存中讀出的數據,很可能就是被刪除的數據,從而導致邏輯錯誤。當然,如果ORM可以根據DELETE SQL對緩存中數據進行處理,將緩存中符合條件的對象廢除,然后再執行DELETE SQL
    ,但是這樣導致緩存的管理復雜性大大增加(實際相當于實現了一個支持SQL的內存數據庫),這對于輕量級的ORM實現而言太苛刻了。
    2.hibernate 3
    性能提高。
    但無法解決緩存同步上的問題,無法保證緩存數據的一致有效性。
    Tuser user = (TUser)session.load(TUser.class, new Integer(1));

    //通過Bulk delete/update 刪除id=1的用戶記錄
    Transaction tx = session.beginTransaction();
    String hql = "delete TUser where id=1";
    Query query = session.createQuery(hql);
    query.executeUpdate();
    tx.commit();

    //再次嘗試加載
    user = (TUser)session.load(TUser.class, new Integer(1));
    可以看到第二次加載是成功的。

    posted on 2006-07-16 10:24 knowhow 閱讀(422) 評論(0)  編輯  收藏 所屬分類: ORM:Hibernate及其他
    主站蜘蛛池模板: 亚洲国产精品视频| 狼友av永久网站免费观看| 亚洲精品无码高潮喷水在线| 激情小说亚洲色图| 免费在线观看黄网| 午夜不卡AV免费| 中文字幕亚洲日本岛国片| 一区二区三区免费视频播放器 | 性xxxxx大片免费视频| 亚洲动漫精品无码av天堂| 亚洲精品免费观看| 亚洲伊人久久大香线焦| 在线免费视频一区二区| 美女视频黄频a免费大全视频| 亚洲国产成人久久综合碰| 波多野结衣免费一区视频| 亚洲综合综合在线| 女人18毛片a级毛片免费视频| 色九月亚洲综合网| 亚洲日韩一页精品发布| 久久精品无码专区免费青青| 亚洲午夜精品一区二区公牛电影院 | 亚洲人成网www| 在人线av无码免费高潮喷水| 亚洲暴爽av人人爽日日碰| 久久久久亚洲av成人无码电影| 麻豆精品成人免费国产片| 亚洲日韩乱码中文无码蜜桃| 免费无码又爽又刺激毛片| 一级毛片免费全部播放| 亚洲国产精品国自产拍电影| 一二三四在线播放免费观看中文版视频 | 亚洲国产精品自产在线播放| 国产精品99久久免费观看 | 国产成人高清亚洲一区91| 在线亚洲精品自拍| 免费精品国产自产拍在线观看图片| 色婷婷亚洲一区二区三区| 亚洲成A∨人片在线观看不卡| 99re热免费精品视频观看| 人人公开免费超级碰碰碰视频|