Hibernate3.0中的session.find()問題

我被Session.find()的方法困擾了好幾天,今天纔看到新的Hibernate裏沒有了Session.find()方法。
現在轉載在此,方便你我。

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

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());
}

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/lulu8785/archive/2007/11/06/1869691.aspx

發佈了17 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章