春季批:子步骤的概念?

时间:2018-12-20 11:46:14

标签: spring spring-batch

我试图了解如何将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,该自定义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; } } 为每个人创建所有行。我真的觉得应该有一种更清洁的方式来做到这一点。 我当前方法的POC:

@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();
}

作业配置:

Disposable scanSubscription = rxBleClient.scanBleDevices(
        new ScanSettings.Builder()
            // .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // change if needed
            // .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) // change if needed
            .build()
        // add filters if needed
)
    .subscribe(
        scanResult -> {
            // Process scan result here.
            Log.v(TAG,"Ble device address: " it.bleDevice.macAddress
        },
        throwable -> {
            // Handle an error here.
        }
    );

// When done, just dispose.
scanSubscription.dispose();

companion object {
   const val TAG = "your_tag_here"
}

任何想法都会受到赞赏

1 个答案:

答案 0 :(得分:1)

您的PoC对我来说看起来不错,我认为您真的不需要在步骤之间创建父/子关系。如果要执行此操作,最接近的方法是使用FlowStep

由于您的Userslist已经抓住了他们的地址和职位,因此无需像使用driving query pattern那样对每个人的详细信息(地址和职位)进行其他查询。对于行聚合器来说也是一样,我将以相同的方式实现它。