2008-11-16 78 views
6

我在數據庫中有大量的行,我需要從中創建一個XML文檔。我使用的是hibernate 3. Criteria和Query接口中的基本list()方法看起來很危險:即使我只是遍歷它們,我也必須將所有記錄讀入內存。還是有一些懶惰的加載魔法?如果沒有,我似乎還剩下兩個選項:使用查詢中的scroll()或iterate()(滾動條件也存在於Criteria中)。如果我想要最小的SQL往返,iterate看起來並不是那麼棒:「第一個SQL查詢只返回標識符」。所以我是對的,我必須爲此使用scroll()嗎?休眠:避免立即將所有記錄讀到內存中

+0

這東西適用於NHibernate以及:) – 2008-11-16 18:02:09

回答

1

在Criteria上使用setMaxResults()方法。

Criteria crit = sess.createCriteria(Cat.class); 
crit.setMaxResults(maxResults); 
crit.setFirstResult(firstResultIndex); 
List cats = crit.list(); 

http://hibernate.org/hib_docs/v3/reference/en/html/querycriteria.html

http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Criteria.html

+0

我想要做的是以事務性的方式獲得所有結果。我認爲你的意思是我應該從各個部分構建整個結果集。我可以使用這些將我一致的大成果集「縫合」在一起,以便從某個特定時間點獲得快照。 – auramo 2008-11-16 19:16:23

+0

我不確定你的意思是「以交易方式獲得所有結果」。 – 2008-11-16 19:23:54

0

這就是我打算做: 所有行的對象ID創建一個臨時表我需要出口:

Insert into BatchTable (ID, Seq) Select (O.ID, Sequence.Next) 
From MyObject O Where ... 

在工作負載的小單位中的對象:

Select Min(B.Seq), Max(B.Seq) From BatchTable; 

for (batch = minBatch; batch <= maxBatch; batch += size) { 
beginTransaction(); 
results = query("Select O From MyObject O, BatchTable B 
        Where O.ID = B.ID and (? <= B.Seq AND B.Seq < ?)"); 

exportXML(results); 
for (MyObject O : results) { 
    O.setProcessed(True); 
    O.update(); 
} 
commit(); 
} 
1

如果您不需要劃去procesed的對象,你可以簡單地使用滾動(),當你與他們進行從會話驅逐的對象。

2

使用try滾動()結合此:

http://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/StatelessSession.html

用於對數據庫進行批量操作阿面向命令的API。

無狀態會話沒有實現一級緩存,也沒有與任何二級緩存交互,也沒有實現事務性的後寫或自動髒檢查,也沒有對相關實例進行級聯操作。集合被無狀態會話忽略。通過無狀態會話執行的操作繞過了Hibernate的事件模型和攔截器。由於缺乏第一級緩存,無狀態會話容易受到數據混疊效應的影響。

對於某些類型的事務,無狀態會話的執行速度可能比有狀態會話略快。