如何在SpringBatch中的FlatFileItemWriter中包含一个计数器,当将行写入csv文件时



因此,我使用FlatFileItemWriter从可以成功从数据库读取的数据中写入csv文件。

我很难写一个整数(即行计数器(,对应于我要写到文件中的行。这似乎是一件容易的事,但很简单,我被难住了。

一切都在工作(文件是从数据库中读取的数据中生成的(。但我似乎不知道如何实现我的getCount((方法,以获得相应行的计数。我认为这与利用ChunkContext有关,但我似乎无法理解。

因此,在我的作业配置中,bean中有以下内容。

@Bean
public FlatFileItemWriter<Customer> customerItemWriter() throws Exception {
FlatFileItemWriter<Customer> itemWriter = new FlatFileItemWriter<>();
itemWriter.setLineAggregator(new CustomerLineAggregator());
itemWriter.setResource(new FileSystemResource("/some/directory/file.csv"));
itemWriter.afterPropertiesSet();
return itemWriter;
}

我还有以下LineAggregator实现。

public class CustomerLineAggregator implements LineAggregator<Customer> {

private ChunkContext chunkContext;

@BeforeChunk
private void beforeChunk(ChunkContext chunkContext) {
this.setChunkContext(chunkContext);
}

@Override
public String aggregate(Customer item) {

return getCount() + "," + convertTime(item.getTime(), 3) + " ET," + item.getCustomerId() + "," + item.getLink() + "," + item.getName();
}


private String convertTime(String timeString, int offset) {

LocalTime timeObject = LocalTime.parse(timeString);

LocalTime timeOffsetObject = timeObject.plusHours(offset);

return timeOffsetObject.toString();

}

private String getCount() {
// how do I make use of the chunk context to infer the integer corresponding to the item assuming my chunk size is 1.
return someCountString;
}

public ChunkContext getChunkContext() {
return chunkContext;
}
public void setChunkContext(ChunkContext chunkContext) {
this.chunkContext = chunkContext;
}

}

预期的输出文件应该如下所示:

1, 10:09 ET, 742, https://www.firm.com, John Doe
2, 12:30 ET, 235, http://www.firm.com, Jane Doe
3, 9:21 ET, 398, http://www.thomas.io, Thomas Chan
4, 14:38 ET, 104, http://www.googl.com, Cindy Chen

除了第一列之外,我可以成功地生成上面的内容,这只是每条记录的行数。我尝试过的任何操作都无法在作业运行之间重置自身。

您可以使用ItemCountAware接口。该接口由您的域对象(在您的情况下似乎是Customer(实现,并将在读取时由任何扩展AbstractItemCountingItemStreamItemReader的读取器调用。

因此,如果你的读者是其中之一,你可以在你的物品上获得物品计数,并根据需要在LineAggregator中使用它。

EDIT:读卡器未扩展AbstractItemCountingItemStreamItemReader时添加选项

您总是可以在ItemReadListener#afterRead中分配项目编号,并在聚合器中使用该编号,例如:

class ItemNumberListener implements ItemReadListener<Customer> {
int number;
@Override
public void afterRead(Customer customer) {
customer.setNumber(number++);
}
// other methods from ItemReadListener
}

一旦就位,您就可以在步骤中注册此侦听器,并在LineAggregator中使用项目编号。此方法适用于所有读卡器(基于游标或基于分页(。

注意:如果你不能在Customer对象中添加一个字段+getter/setter(可能是一个你不能修改的类(,你可以将它包装在一个像NumberAwareCustomer这样的自定义对象中,并在你的批处理应用程序中使用该类型。

最新更新