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

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

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

    Topquan's Blog

    分享價值----成就你我----我的博客----你的家

    hibernate數據加載

    單一數據加載: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-08-05 01:19 topquan 閱讀(1815) 評論(0)  編輯  收藏 所屬分類: Hibernate

    主站蜘蛛池模板: 久久精品国产亚洲7777| 免费无码又爽又刺激高潮| 亚洲综合另类小说色区| 成人久久久观看免费毛片| 亚洲国产成人久久综合区| 精品成人一区二区三区免费视频 | 最近中文字幕免费mv视频7| 亚洲一区二区三区国产精品无码| 国产精品入口麻豆免费观看| 亚洲一区二区三区91| 九九九精品成人免费视频| 亚洲经典千人经典日产| 国产乱子伦精品免费无码专区| 欧美激情综合亚洲一二区| 亚洲熟伦熟女新五十路熟妇 | 51午夜精品免费视频| 中文字幕亚洲乱码熟女一区二区| 香蕉免费看一区二区三区| 亚洲国产一区在线| 成年免费大片黄在线观看岛国| 亚洲精品亚洲人成在线| 亚洲情a成黄在线观看| 美女在线视频观看影院免费天天看| 久久亚洲国产成人精品性色| 国内精品乱码卡1卡2卡3免费| 亚洲欧洲无卡二区视頻| 久久久久亚洲精品天堂久久久久久| 中国内地毛片免费高清| 亚洲沟沟美女亚洲沟沟| 国产精品国产自线拍免费软件| 国产免费黄色无码视频| 亚洲国产高清视频在线观看| 成人免费视频国产| 曰批全过程免费视频在线观看无码| 亚洲另类精品xxxx人妖| 亚洲精品成人久久久| 永久免费在线观看视频| 美女视频免费看一区二区| 亚洲视频一区在线播放| 免费大片黄手机在线观看| 69视频在线观看高清免费|