2010-04-27 87 views
1

我們試圖迭代數據庫中的大量行並將其轉換爲對象。行爲如下:在JDBC/iBatis 3中迭代大型結果集的最佳方法是什麼?

  • 結果將按序列號排序,當序列號發生變化時將創建一個新對象。創建的對象將被髮送到外部服務,有時必須等待,然後再發送另一個數據(這意味着下一組數據將不會立即使用)
  • 我們已經在iBatis 3中投入了代碼,因此iBatis解決方案將會對我們來說是最好的方法(我們已經嘗試過使用RowBounds,但沒有看到它如何進行迭代)。
  • 我們想平衡最小化內存使用量和減少數據庫行程。
  • 我們也接受純粹的JDBC方法,但我們希望解決方案能夠在不同的數據庫上工作。

更新1

  • 我們需要儘量少調用DB越好(1次調用將是理想的情況下),同時還防止使用過多內存的應用程序。這種類型的問題有沒有其他解決方案可能是純JDBC或任何其他技術?

UPDATE 2

  • 查詢將後端驅動並且將只有1個實例在給定時間執行。

感謝並希望聽到您對此的見解。

回答

0

看來你需要某種分頁。 iBatis通過查詢中的標準LIMIT/OFFSET參數(以及iBatis 3中的RowBounds)執行此操作。

但似乎(如果我正確的話)您還使用iBatis的GROUP BY功能,以便選擇返回帶有N1 distint「idx」字段的N個記錄,從而創建N1「父」對象每個人有幾個子對象(總共創建了N個子對象)。或類似的東西。

不幸的是(可以理解)do not mix well

我沒有在這裏看到任何銀彈,人們可以想到很多方法,每種方法都有其缺點 - 很難評估沒有更多的信息。

如果主要對象是「大」(許多記錄),並且每一個都將被單獨處理(通過遠程服務器訪問),你甚至可能想要做一個臨時分頁,每頁有一個對象,內部記住previosuly讀取ID(類似SELECT ... FROM ... WHERE id = (SELECT MIN(id) FROM .... WHERE id > #lastid#))

+0

1.我有一種感覺,iBatis使用LIMIT/OFFSET,我想這意味着它需要爲每個頁面打對數據庫? 2.我們在Java端進行分組,因此不需要在查詢中使用group by關鍵字,我們只需要將結果按id排序,這樣我們就可以在處理之前完成使用相同id的子項創建一個對象下一個對象。 3.您的adhoc分頁聽起來像是RowBounds方法的一個很好的選擇。這樣我們保證只有下一個對象會被檢索。我會給你一個嘗試和檢查性能。 感謝您的幫助leonbloy! – 2010-04-28 01:56:01

+0

我添加了一個新的要求,即儘可能減少DB往返次數。希望您也可以對更新發表評論。謝謝! – 2010-04-28 10:36:50

+1

我堅持要在一個數據庫查詢中這樣做,看看RowHandler或ResultHandler - (或者更加異常地,返回一個ResultSet/Cursor - 或者還原爲普通的JDBC)。但是,如果爲每個「對象」遠程完成的動作應該給出響應(快速 - 不依賴於某些人爲交互),並且您可以相信循環將完成,那麼這是合理的。 – leonbloy 2010-04-28 13:36:16

1

我們需要儘量少調用DB越好(1次調用將是理想的情況下),同時還防止使用過多內存的應用程序。這種類型的問題有沒有其他解決方案可能是純JDBC或任何其他技術?

你真的不應該擔心數據庫調用的數量。只需查詢最終用戶需要一次查看的數據。它不能更有效地完成。谷歌也不會查詢整個數據庫,只顯示前10個數字。不,它正好查詢那10個數據以供顯示,無一例外。這比將整個數據庫拖入/複製到應用程序的內存並對其進行處理要快得多,效率更高。利用RDBMS的力量。這就是它的發明/意圖。

+0

謝謝BalusC。對不起,但我忘了提及這不是一個用戶驅動的查詢,而是一個由後端觸發的查詢。不知道爲什麼老闆想要一個數據庫調用,我提到它可能很難平衡內存使用方式,但他建議繼續嘗試這是爲什麼我仍然在尋找其他的選擇。 – 2010-04-28 13:26:49

+0

+1 BalusC是對的,一般來說(我懷疑特別也是) – leonbloy 2010-04-28 13:30:08

+1

@保羅:好吧,如果老闆說的話......:/和他說話。說服他更多。 – BalusC 2010-04-28 13:46:27

相關問題