2011-10-20 109 views
4

我有以下要求,但我不能對方法決定採取行的變量數:彈簧批量多行記錄項作家,每個記錄

我需要將數據寫入到一個固定的格式進行放文件,其中每個記錄跨越多行,如下所示:

000120992599999990000000000000009291100000000000000000000000010000 
000000000000000000000006050052570009700000050000990494920000111100 
     ABCDE:WXYZ            0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
000000000000000000000006050052730005700001100000090494920000221200 
     ABCDE:WXYZ            0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
000000000000000000000006050113110009700000000000000494920000311100 
     ABCDE:WXYZ            0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
000012099259999999000000000000000929110000000000000000000000001000 

這是從例如上述的一個記錄:

000000000000000000000006050052570009700000050000990494920000111100 
     ABCDE:WXYZ            0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 
     descriptiongoesheredescriptiongoesheredescriptiongoesher0200 

第一和最後一行是報頭和Foo ter分別。 每條記錄​​的第一行包含幾個細節。 第二行有一些其他的空間細節。

我有一個很長的描述字段,我需要分成56個字符部分,並附加記錄的第3行向前。

所以在一些記錄中,這可能只是一條線,而在一些記錄中也可能是三條線。

我需要關於如何在上述場景中設計我的作品的指導。

回答

4

有官方spring-batch-samples多行記錄的作家例如,搜索multiline.xmlMultiLineTradeItemWriter

它基本上平時的委託原則,你只需要一個適當的域對象與那些supposable列表1..n中間線

public class MultiLineTradeItemWriter implements ItemWriter<Trade>, ItemStream { 

    private FlatFileItemWriter<String> delegate; 

    public void write(List<? extends Trade> items) throws Exception { 
       List<String> lines = new ArrayList<String>(); 
       for (Trade t : items) { 
       lines.add("BEGIN"); 
       lines.add("INFO," + t.getIsin() + "," + t.getCustomer()); 
       lines.add("AMNT," + t.getQuantity() + "," + t.getPrice()); 
       lines.add("END"); 
      } 
      this.delegate.write(lines); 
    } 
    } 
+0

謝謝邁克爾..通過例子! – Nik

+0

它工作。謝謝!! – Nik

0

你可以在CustomExtractor中做到這一點。

例如:

 public Object[] extract(T item) { 
     List<Object> values = new ArrayList<Object>(); 

     BeanWrapper bw = new BeanWrapperImpl(item); 
     for (String propertyName : this.names) { 
      values.add(bw.getPropertyValue(propertyName) + "\r\n"); 
     } 
     return values.toArray(); 
    } 
0

我有一個類似的問題,寫多行到數據庫。由於作業步驟將創建項目列表,因此如何將處理器的List返回給作者?這將創建列表清單,並且Writer中的doWrite方法未設置爲處理該方案。

我使用的是1.2.0 spring-boot-starter-parent(它給了我spring-core 4.1.3)以及hibernate(4.3.7),在我的例子中我有'應收賬款',並且對於每一個1我從csv文件中讀取的應收賬款,然後我可能需要更新或插入許多應收賬款到我的表中。我也使用HibernateItemWriter。

我的解決方案是擴展HibernateItemWriter。 sessionFactory字段是私有的,所以我通過構造函數傳遞它,並使用setter(以獲取現有代碼)。所以,我的原代碼(這對於一個單獨的「應收賬款」正常工作)原本是這樣的:

@Bean 
    public ItemWriter<Receivable> recivableWriter() { 
     HibernateItemWriter<Receivable> hibernateItemWriter = new HibernateItemWriter<Receivable>(){{ setSessionFactory(sessionFactory); }}; 
     return hibernateItemWriter; 
    } 

延長HibernateItemWriter和修改我的處理器返回一個列表後,我的代碼更改爲:

@Bean 
    public ItemWriter<List<Receivable>> receivableWriter() { 
     HibernateListItemWriter<List<Receivable>> hibernateItemWriter = new HibernateListItemWriter<List<Receivable>>(this.sessionFactory){{ setSessionFactory(sessionFactory); }}; 
     return hibernateItemWriter; 
    } 

而我的擴展類看起來像這樣(我可能會清理它,但這是我的第一遍。我還希望把SessionFactory和clearSession領域是不是私人)

package com.work; 

import java.util.ArrayList; 
import java.util.List; 

import org.hibernate.SessionFactory; 

public class HibernateListItemWriter<Receivable> extends org.springframework.batch.item.database.HibernateItemWriter<Receivable> { 

    public HibernateListItemWriter(SessionFactory sessionFactory) { 
     super(); 
     this.sessionFactory = sessionFactory; 
    } 

    private SessionFactory sessionFactory; 
    private boolean clearSession = true; 

    @Override 
    public void write(List items) { 
     List<Receivable> unwrappedItems = new ArrayList<Receivable>(); 
     List<List<Receivable>> wrappedItems = (List<List<Receivable>>)items; 
     for (List<Receivable> singleList: wrappedItems) { 
      unwrappedItems.addAll(singleList); 
     } 
     doWrite(sessionFactory, unwrappedItems); 
     sessionFactory.getCurrentSession().flush(); 
     if(clearSession) { 
      sessionFactory.getCurrentSession().clear(); 
     } 
    } 

} 

大喊出grepcode.com製作的生活更輕鬆。