Spring Batch 中的多个 Writer 具有不同的实体

Spring Batch 中的多个 Writer 具有不同的实体

问题描述:

初始代码:

Tasklet 类被定义为有 3 个方法:

Tasklet class was defined where there are 3 methods:

    class Tasklet{
        doBeforeStep(){
        //Records a retrieved from the table.
        }

        doExecute(){
        //It opens the file and reads the file.
        //Does all the processing one by one and creates a 2 list of records to update into the database.
        }

        doAfterStep(){
        //The 2 list of records(Entities) are saved into the 2 different tables database using its corresponding repository class. Example:
RepositoryClass.saveall(List containing 105,000 records)  //using the CRUDRepository method
        }
    }

面临的问题:该文件包含 150,000 条记录,因此,在 doExecute() 方法之后,它在列表中存储了 150,000 条数据记录.在 doAfterStep() 方法中,它尝试将列表中的所有 150,000 条记录保存到数据库中,因此出现事务超时错误.

Issue faced: The file contains 150,000 records and therefore, after doExecute() method, it stores in the list 150,000 records of data. And at the doAfterStep() method, it tries to saveall the 150,000 records in the list to the database and hence the Transaction Timeout error.

解决方法:

  • 尝试将上面的类重新设计为ItemReader、ItemProcessor和ItemWriter,这样我就可以引入Chunk的概念,并尝试一次更新1000条记录并继续循环.-- 这种方法的问题:在块概念的情况下,我们需要提及传入实体和传出实体,例如:

  • try to redesign the above class into ItemReader, ItemProcessor and ItemWriter so that I can introduce the concept of Chunk and try to update like 1000 records at a time and keep on looping it. -- Problem in this approach: In case of Chunk concept, we need to mention the Incoming Entity and the Outgoing entity like:

            .get("stepToReadDataFromFile")
            .<Entity1, Entity2>chunk(1000)        
            .reader(FileReader()) 
            .processor(Processor())
            .writer(Writer())
            .build();```

但情况是,它会从文件中读取,(可能是Entity1)然后将其写入2个表(即2个实体).我们如何在这里定义这两个实体.

But the situation is, it will read from the File, (may be Entity1) and then write it to 2 Tables (that means 2 Entities). How can we define here the 2 Entities.

  • 还将数据从一个类发送到另一个类,例如:在 ItemReader 中,ItemReader 的结果通过这个发送到 ItemProcessor:

  • Also sending the data from one class to another like: in ItemReader, the result of ItemReader is sent to ItemProcessor via this:

public class FileReader extends Itemreader

在ItemProcessor中,ItemProcessor的结果通过以下方式发送给ItemWriter:

In ItemProcessor, the result of ItemProcessor it sent to ItemWriter via :

public class FileProcessor extends ItemProcessor<Entity1, Entity2> {

现阶段我们如何在这里发送 2 个实体,Entity2 和 Entity3?

How can we send 2 Entities here at this stage, Entity2 and Entity3?

您可以将 Entity2Entity3 组合在一个对象中并调整 ItemProcessorcode> 返回这个组合对象.例如:

You can combine both Entity2 and Entity3 in one object and adjust the ItemProcessor to return this combined object. For example :

public class ProcessResult {

    private Entity2 e2;
    private Entity3 e3;
} 

ItemProcessor 看起来像:

And the ItemProcessor looks likes:

public class FileProcessor extends ItemProcessor<Entity1, ProcessResult> {


    public ProcessResult process(Entity1 e1){
        //processing ....

        return new ProcessResult(entity2 , entity3);
    }
}

ItemWriter 中,您可以从 ProcessResult 访问 Entity2Entity3.

In the ItemWriter , you can then access the Entity2 and Entity3 from the ProcessResult.