【问题标题】:Spring Batch - Read from DB - Transform - And write to fileSpring Batch - 从数据库读取 - 转换 - 并写入文件
【发布时间】:2019-09-12 02:42:01
【问题描述】:

我正在探索 Spring 批处理,我有一个问题陈述,需要我从 db 中读取,将这些数据转换为逗号分隔的形式并写入文件。我有大约 50 个不同的查询和尽可能多的文件要创建。这些查询很少会返回大量数据,这可能会使我的文件变大。我正在使用 Spring Batch 解决这个问题,并且一般对 Spring Batch 的查询很少。

  1. 当我需要转换特定字段值时,是否可以使用字段提取器。

BeanWrapperFieldExtractor<StudentDTO> extractor = new BeanWrapperFieldExtractor<>();
extractor.setNames(new String[] {"name", "emailAddress", "purchasedPackage"});
lineAggregator.setFieldExtractor(extractor);

例如,如果我需要执行类似 studentDto.getName().replace("a","") 的操作。在这种情况下我应该选择定制处理器吗?

  1. 在这种情况下,一项具有 50 个步骤和并行处理的作业是否适合进行?
  2. 将标题写入文件顶部而不是使用 FlatFileHeaderCallback - 以下写入文件的方式是否可接受?

@Override
public ExitStatus afterStep(StepExecution stepExecution) {
   if (stepExecution.getStatus() == "COMPLETED") {
   
      fileWriter.write("headerString");
      Path path = Paths.get("encryptedTextFileThreaded.txt");
      try (BufferedWriter fileWriter = Files.newBufferedWriter(path)) {
        for(Line line: studentDtoLines)
        {
          fileWriter.write(line.getLine());
          fileWriter.newLine();
        }
      
      fileWriter.write("footerString");
  }
  catch (Exception e) {
      log.error("Fatal error: error occurred while writing {} file",path.getFileName());
  }
}
    
   
  1. 多线程步骤用于加速单个步骤。如果我有一个包含 50 个步骤的 Job,并且没有一个步骤依赖于另一个,那么可以使用并行处理来加速 Job 的执行。真的?这是否意味着 Spring Batch 可以创建 50 个线程并并行运行所有线程?

【问题讨论】:

标签: java spring spring-batch


【解决方案1】:
  1. 当我需要转换特定字段值时,是否可以使用字段提取器。在这种情况下,我应该选择定制处理器吗?

我会使用处理器进行数据转换。这是项目处理器的典型用例。让每个组件做一件事情(并且做得很好)是一个很好的做法:字段提取器用于提取字段,而项目处理器用于进行转换。这更有利于测试和可重用性。

  1. 在这种情况下,一项包含 50 个步骤和并行处理的作业是否适合进行?

出于可重新启动的原因,IMO 为每个文件分配一个作业是更好的选择。当文件处理失败时,最好(更干净)为该特定文件重新启动失败的作业,而不是相同的作业并跳过 49 个步骤。通过在JobLauncher 上使用适当的任务执行器,您始终可以并行运行多个作业。

  1. 将标题写入文件顶部而不是使用 FlatFileHeaderCallback - 以下写入文件的方式是否可接受?

不,这是对侦听器的错误用法。我会使用页眉/页脚回调来编写页眉/页脚,并使用面向块的步骤来编写文件的内容。

  1. 多线程步骤用于加速单个步骤。如果我有一个包含 50 个步骤的 Job,并且没有一个步骤依赖于另一个,那么可以使用并行处理来加速 Job 的执行。真的?这是否意味着 Spring Batch 可以创建 50 个线程并并行运行所有线程?

没错。并行度可在您对并行流设置的TaskExecutor 中进行配置。详情请见Parallel steps

【讨论】:

  • 如果我为所有文件制作独立的作业,我如何从每个作业中获取数据并在最后合并它。例如,如果我需要创建第 51 个文件,其中包含我创建的所有 50 个文件的名称以及其中的记录数或相应文件的哈希值等详细信息?顺便说一句,很高兴从您那里得到答案。我看到了关于“高性能批处理”的会议!
  • 非常希望您喜欢这次会议!如果要汇总结果,可以在单独的作业中进行(读取生成的文件)。您可以尝试的另一个有趣的概念是通过JobStep 使用作业作业,并且聚合是“主”作业结束时的常规步骤。希望这会有所帮助。
猜你喜欢
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 2020-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多