代码之家  ›  专栏  ›  技术社区  ›  Tyvain

Springbatch处理器:在这种情况下是什么对象?

  •  0
  • Tyvain  · 技术社区  · 6 年前

    我有一个输入数据库myinpuntety,比如:

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

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

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

    项处理器如下所示:

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

    这里的问题是,这个人被处理成100块。所以代码保存在Everyline上,每100行保存一个人。

    我觉得有问题,应该换个方法,但我不知道怎么办?我应该为“代码”创建另一个处理器吗?在这种情况下,最佳实践是什么(对于Everyline,在多表中创建)?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Mahmoud Ben Hassine    6 年前

    我建议创建一个包装类,例如 MyOutputEntity 封装的 OutPerson OutCode . 这个类将是处理器的输出和编写器的输入。作者将在同一个事务中同时插入人员和代码(这样在失败的情况下,您的数据是一致的)。例如:

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

    希望这有帮助。

        2
  •  2
  •   Igor Konoplyanko    6 年前

    我建议继续把所有的逻辑写进作家,因为这就是作家的目的。 我认为最好的方法是在编写器中同时编写代码和人员(假设这是相同的数据库,所以它们将在相同的事务中编写)。

    但请注意,它们将用块写入= chunk(100)

    这样,当对数据库的一次写入可能因任何错误而失败时,您还可以从Spring批处理的回退机制中获益。根据目前的情况,我认为你需要自己解决。