2009-08-27 70 views
17

當使用各種JDBC模板方法之一時,我對如何遍歷/滾動大型結果集(不適合內存)感到困惑。即使沒有Iterable接口的直接暴露,我也會至少期望RowCallbackHandler的實例被調用,而查詢在完成後(或堆溢出)不會執行。Spring JDBC支持和大型數據集

我確實在this看看一個(這對我來說什麼都沒有改變,儘管是在精神this post在堆棧溢出類似),並在this後在春季論壇。後者似乎表明,在光標獲取數據時,回調處理程序確實應該被調用。然而我的測試顯示沒有這樣的行爲。

的數據庫是Oracle10g中。我正在使用11.1.0.7.0-Production驅動程序和Spring 2.5.6.SEC01。任何人想法如何迭代結果集,最好同時保持RowMapper的映射邏輯等?

回答

19

Oracle JDBC驅動程序對java.sql.Statement上的setFetchSize()方法提供了適當的支持,允許您控制驅動程序一次可以提取多少行。

但是,Spring使用的RowMapper通過將每行讀入內存,獲取RowMapper將其轉換爲對象並將每行對象存儲在一個大列表中。如果結果集很大,那麼不管JDBC如何獲取行數據,這個列表都會變大。

如果您需要處理大型結果集,則RowMapper不可縮放。您可以考慮使用RowCallbackHandler,以及JdbcTemplate上的相應方法。 RowCallbackHandler並不指示如何存儲結果,而是由您來存儲它們。

+1

setFetchSize並沒有改變我的東西,我嘗試過使用它。您是否針對Oracle實例開發?對我來說RowCallBackHandler只是掛起,等待查詢完成,因爲我在我的OP中寫道。 – yawn

+2

顯然我在測試中的JDBC模板上忘記了afterPropertiesSet()之後的調用。尷尬,但現在它的工作原理:*) – yawn

4

這是驅動程序/連接是否將數據流式傳輸回給您或者是否將其發送回一個塊的屬性。例如,在SQL Server中,您使用的連接URL的SelectMethod屬性:

jdbc:microsoft:sqlserver://gsasql03:1433;DatabaseName=my_db;SelectMethod=direct

direct值意味着其結果應該進來一氣呵成。另一個選擇是cursor,它允許您指定要連接到流結果反饋給你。我不確定什麼樣的數據源是Oracle數據源,恐怕

RowCallbackHandler肯定適合我。

+0

是的,最好你不要放到一個數據集,你會抓住記錄,同時堅持讓連接打開,詢問是否有更多的記錄。我在.NET中做到了這一點,並在性能方面有了很大的提升。我想象一下類似的java會存在,特別是在春天。 – Zoidberg

+0

@ * Zoidberg * - OP似乎在做正確的事情,使用行回調處理程序 –

+0

這聽起來很有希望。不幸的是,我在Oracle JDBC文檔中找不到與此SQL Server URL設置類似的任何內容。 – yawn

-2

這裏是將java sql結果集全部拉入內存的一個好庫。通過數據集

http://casperdatasets.googlecode.com

您可以滾動/迭代,你可以發出對其進行查詢,並建立索引優化。它還實現了java.sql.resultset接口,以便您可以繼續使用此數據集的結果對JDBC數據庫進行最小化操作。

+0

它也有一個適配器將jdbc結果集轉換爲內存結果集 - 我假設你可以在你的spring jdbc結果回調方法中調用這個適配器。 –

+1

對不起,但「如何迭代/滾動大型結果集(*不適合內存*)」。 – yawn

5

您可以使用springjdbc-iterable庫:

CloseableIterator<MyObj> iter = jt.queryForIter("select ...", params, mapper); 

迭代器將自動關閉,在耗盡或者可以手動關閉。它只能在事務範圍內工作。

免責聲明:我寫這個庫

0
  1. 創建擴展StoredProcedure
  2. 創建RowCallBackHandler,可以同時處理每一行,一個自定義的存儲過程。
  3. 聲明你的參數。如果您有結果集,請首先聲明該結果集。使用SqlReturnResultSet類和使用您的RowCallBackHandler
  4. 聲明任何其他參數創建
  5. 編譯
  6. 我做的步驟2至5在我的客戶的存儲過程
  7. 的構造函數創建一個地圖包含你輸入參數
  8. 使用輸入參數執行存儲過程

我會提供代碼,但下面的文章包含所有這些信息。

Calling Stored Procedures with Spring JDBC Templates