我是Spring Batch的新手,我有点失去了我需要完成的这个批处理工作,我想知道你是否有人可以告诉我如何正确地做正确的事情在这种情况下。
我的需要基本上是接收一个文本文件,其中包含多行带有固定长度分隔的字段行,并将它们组成一个POJO,然后通过REST将其发送到另一个应用程序,使用Spring Data JPA进行持久化,之后持久性完成后,这个作业将写一个带有它处理状态的.txt文件。
我已经将这个例程用于使用BeanIO的普通Java实现,但我需要在此要求中使用Spring Batch,因此有些事情必须改变。
我有一个.txt文件,其格式如下:
00XXXXX...b
01XXXXX...n
02XXXXX...n
01XXXXX...n
02XXXXX...n
03XXXXX...n
99XXXXX...n
并将我的POJO结构视为:
public class POJO {
private String headerId; // Data from record 00
private List<Child> children; // Every entry for record 01
private String trailerId; // Data from record 00
}
public class Child {
private String headerId; // Data from record 00
private String childId; // Data from record 01
private String name; // Another data from record 01
private ChildAttribute attr; // Entry for record 02 following record 01
private AnotherChildAttribute attr; // Entry for record 03 following record 01
}
public class ChildAttribute {
private String childId; // Data from record 01
private String name; // Data from record 02
}
现在,我在Spring Batch中做到的最好的事情是使用FlatFileItemReader创建一个单步作业,它为每种类型的记录实现多个LineTokenizer(稍后将被BeanIO取代),从正确的数据传递数据处理器,然后将文件写入另一个文件。
@Bean
@StepScope
public ItemStreamReader<Person> reader(@Value("#{jobParameters['filePath']}") String filePath) throws Exception {
return new FlatFileItemReaderBuilder<Person>()
.name("reader")
.resource(resourceLoader.getResource(filePath))
.lineMapper(personLineMapper())
.build();
}
@Bean
public LineMapper<Person> personLineMapper() {
DefaultLineMapper<Person> mapper = new DefaultLineMapper<Person>();
mapper.setLineTokenizer(personLineTokenizer());
mapper.setFieldSetMapper(new PersonFieldSetMapper());
return mapper;
}
//Sample.. I already have more complex tokenizers implemented
@Bean
public LineTokenizer personLineTokenizer() {
FixedLengthTokenizer tokenizer = new FixedLengthTokenizer();
tokenizer.setColumns(new Range[] { new Range(1, 7), new Range(8, 14) });
tokenizer.setNames(new String[] { "firstName", "lastName" });
return tokenizer;
}
@Bean
public ItemProcessor<Person, Person> processor() {
return new PersonItemProcessor();
}
@Bean
public ItemWriter<Person> writer() {
/* Writer */
}
@Bean
public Job ingestJob() throws Exception {
return jobBuilderFactory.get("ingestJob")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.build();
}
@Bean
public Step step1() throws Exception {
return stepBuilderFactory.get("ingest")
.<Person, Person>chunk(10)
.reader(reader(null))
.processor(processor())
.writer(writer())
.build();
}
所以我需要的是,而不是读取,处理和逐行编写,在读取每一行时复合我的Pojo,并且在读完最后一行后才调用持久层。
实现这一需求的最佳方法是什么?此外,你们所拥有的任何代码都将非常感激!
感谢您的关注。
祝你好运, 恩里科