2013-08-27 51 views
0

我的情況:如何在spring批處理中使用itemWriter編寫子記錄

我有我從readerItem中的db讀取的類A.然後我需要處理這個類A,並在itemProcessor中創建類B。最後,我將這個B類保存到itemWriter中的db中。

問題:在處理過程中,我還需要創建具有B類外鍵的C類(約1 mil記錄)並保存該類C.我應該如何執行此操作。

我不能這樣做: 因爲正如我寫的,我有大約1萬個記錄,我應該需要在內存中存儲什麼是大約2GB的空間。那麼我應該如何解決這個問題。

public class BWriter extends BaseItemWriter<B> { 

    public void write(List<? extends B> data) throws Exception { 
     logger.info("Start writing: " + data); 
     for (B item : data) { 
      myCustomDao.saveB(item); 
      for (C itemC : item.getC()) { 
       itemC.setB(item); 
       myCustomDao.saveC(itemC); 
      } 
     } 
    } 
} 

UPDATE:

可能的解決方案,其犯規包括彈簧批次,我想:

List<C> cList = new ArrayList<C>(); 
    int i = 0; 
    String line; 
    while ((line = reader.readLine()) != null) { 
     String[] data = line.split(";"); 
     if (data.length > 1 && !StringUtils.isBlank(data[1])) { 
      C cItem = new C(); 
      cItem.set(...); 
      cList.add(i, cItem); 
      if (++i >= 1000) { 
       myCustomDao.save(cList); 
       cList = new ArrayList<C>(); 
       i = 0; 
      } 
     } 
    } 
    if (!cList.isEmpty()) 
       myCustomDao.save(cList); 
+0

'B.getC()':它會返回一個迭代器嗎?你可以發佈'B'的代碼嗎? – bpgergo

+0

它返回C項的列表 – hudi

+1

但每個B有1mil C? –

回答

0

如果減少commit-interval爲小的值在不是一種選擇,因爲一個B元素最多能有1mil C對象,您可以這樣做:

將類A處理到類B,而不在已處理的B對象中創建C對象;
在您的BWriter附加一個ItemWriteListener<B>.afterWrite()您可以創建/保存C對象(與在監聽器中接收的List<B>相關),因此您的內存消耗量很低,但您可以保證在事務邊界內工作。

如果問題是由於使用Hibernate而不是普通JDBC引起的,您可以考慮手動使用無狀態會話或flush()/clear()會話;數據庫的1mil記錄不是一個大數字
不幸的是,當您有大量數據時,ORM不是最佳選擇。

我的2美分,與你一樣,我是Spring批次的新手。

相關問題