SpringBatch Processor:在这种情况下是什么对象?

时间:2018-10-22 05:03:17

标签: spring-batch

我有一个输入数据库MyInputEntity,可以这样说:

id, name, someCode
1,john,code_abc
2,jack,code_xyz

此文件由spring批处理作业处理,它的每一行都会在这2个表中创建一行:

OutPerson:
id
name

OutCode:
code

配置为:

@Bean
public Step step3_readDBWriteDB(OutCodeRepository outCodeRepository) {
    return stepBuilderFactory.get("step3_readDBWriteDB")
            .<MyInputEntity, OutPerson>chunk(100)
            .reader(myReader())
            .processor(new MyItemProcessor(outCodeRepository))
            .writer(myWriter()).build();
}

itemProcessor是这样的:

@Override
 public OutPerson process(MyInputEntity myInput) {       
        // creation of Person
        OutPerson outPerson = MyMapper.convert(myInput);

        // Create and save outCode
        OutCode outCode = new outCode(myInput.getCode());
        OutCodeRepository.save(outCode)

        return outPerson;
    }

这里的问题是,Person用100的块进行处理。因此代码保存在每一行上,而person每100行保存一次。

我认为这里有问题,应该以不同的方式进行,但是我不知道怎么办?我应该为“代码”创建另一个处理器吗?在这种情况下(对于每一行,在多表中创建)的最佳做法是什么?

2 个答案:

答案 0 :(得分:2)

我建议将所有写作逻辑都保留在作家中,因为这就是作家的目的。 我认为最好的方法是在编写器中一起编写代码和人员(假设这是同一数据库,因此它们将在同一事务中编写)。

但是请注意,它们将以大块= chunk(100)

写入

这样,当一次写入数据库失败并出现任何错误时,您还可以从spring批处理的回退机制中受益。在目前的情况下,我认为您需要自己解决。

答案 1 :(得分:1)

我建议创建一个名为MyOutputEntity的包装器类,该包装器封装OutPersonOutCode。此类将是处理器的输出和编写器的输入。编写者将在同一事务中将人员和代码一起插入(因此在失败的情况下您的数据是一致的)。例如:

class MyOutputEntity {
   private OutPerson outPerson;
   private OutCode outCode;
   // getters and setters
}

public ItemProcessor<MyInputEntity, MyOutputEntity> itemProcessor() {
    return myInputEntity -> {
        // create Person
        OutPerson outPerson = MyMapper.convert(myInputEntity);

        // Create outCode
        OutCode outCode = new outCode(myInputEntity.getCode());

        MyOutputEntity myOutputEntity = new MyOutputEntity();
        myOutputEntity.setOutPerson(outPerson);
        myOutputEntity.setOutCode(outCode);

        return myOutputEntity;
    };
}

public ItemWriter<MyOutputEntity> itemWriter() {
    return items -> {
        for (MyOutputEntity outputEntity : items) {
            outPersonRepository.save(outputEntity.getOutPerson());
            outCodeRepository.save(outputEntity.getOutCode());
        }
    };
}

希望这会有所帮助。