【问题标题】:Spring batch: Concept of child steps?春季批次:子步骤的概念?
【发布时间】: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


    【解决方案1】:

    您的 PoC 对我来说看起来不错,我认为您真的不需要在步骤之间创建父/子关系。如果您想这样做,您可以获得的最接近的方法是使用FlowStep

    由于您的RepositoryItemReader 已经获取了带有地址和工作的人员,因此无需像使用driving query pattern 那样对每个人的详细信息(地址和工作)进行额外查询。线聚合器也是如此,我会以相同的方式实现它。

    【讨论】:

      猜你喜欢
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-13
      • 1970-01-01
      • 1970-01-01
      • 2018-06-23
      相关资源
      最近更新 更多