【发布时间】:2018-12-20 11:46:13
【问题描述】:
我正在尝试了解如何将 Spring Batch 的概念应用到我们的用例中。
我们必须从数据库中读取数据并从中创建一个固定长度的平面文件。具体来说,数据库将类似于:
|---------| |---------|
| Person | 1----n | Address |
|---------| |---------|
1
|
n
|---------|
| Job |
|---------|
输出文件将如下所示:
PERSON1HEADER
PERSON1INFORMATION
ADDRESS1.1
ADRRESS1.2
JOB1.1
PERSON1FOOTER#OFADDRESS2#OFJOB1
PERSON2HEADER
PERSON2INFORMATION
ADDRESS2.1
JOB2.1
JOB2.2
PERSON2FOOTER#OFADDRESS1#OFJOB2
我的第一个想法是创建一个开始步骤“人”的工作。然后 Person 步骤将从数据库中加载所有信息,并为 每个 人启动更多步骤,例如地址和工作步骤。
这个想法是在我无法在 JavaConfig 中创建的步骤之间建立某种父子连接。
当前的想法是创建一个自定义LineAggregator,它为每个人创建所有行。我真的觉得应该有一种更清洁的方法来做到这一点。
我当前方法的 POC:
public class MyLineAggregator implements LineAggregator<Person> {
private Map<String, LineAggregator<Person>> aggregators;
@Override
public String aggregate(Person item) {
StringBuilder builder = new StringBuilder();
builder.append(aggregators.get("person").aggregate(item) + LINE_ENDING);
for(Address address : item.getAddress()) {
builder.append(aggregators.get("address").aggregate(address) + LINE_ENDING);
}
for(Job job : item.getJob()) {
builder.append(aggregators.get("job").aggregate(job) + LINE_ENDING);
}
return builder.toString();
}
public void setAggregators(Map<String, LineAggregator<Person>> aggregators) {
this.aggregators = aggregators;
}
}
工作配置:
@Bean
public FlatFileItemWriter<Person> itemWriter3(MyLineAggregator myLineAggregator) {
return new FlatFileItemWriterBuilder<Person>()
.name("flatfile")
.resource(new FileSystemResource("target/test-outputs/output.txt"))
.lineAggregator(myLineAggregator)
.build();
}
@Bean
public Step testStep(FlatFileItemWriter<Person> itemWriter3) {
RepositoryItemReader<Person> repoReader = new RepositoryItemReaderBuilder<Person>()
.repository(personRepo)
.sorts(Map.of("personId", Sort.Direction.ASC))
.saveState(false)
.methodName("findAll").build();
return stepBuilderFactory.get("testStep")
.<Person, Person>chunk(10)
.reader(repoReader)
.writer(itemWriter3)
.build();
}
任何想法将不胜感激
【问题讨论】:
标签: spring spring-batch