如何批量筛选项目?

How to filter items in bulks?

我正在使用 Spring 批处理执行作业,我的简单场景是:

  1. 从文件中读取项目
  2. 处理每个项目
  3. 将项目块写入数据库

问题是我想过滤掉数据库中已经存在的项目。

我的第一个尝试是在第二步中查询数据库以获取当前项目,如果已​​经存在,则从 ItemProcessor 中查询 return null 以便过滤掉该项目。 这是不必要的慢,因为每个处理的项目都需要一个查询。

所以我的第二次尝试是重写 ItemWriter 中的 doWrite 方法,对整个块进行一次查询,并仅写入与查询不匹配的项目。 即使性能有了很好的提高,这对我来说也不太好(这样 Spring Batch 看不到我实际写入数据库的内容,实际上 StepContext 的写入和过滤计数器值错误).

实现这个处理逻辑的正确方法是什么?

在 ItemWriter 的开头执行单个 select 以查找现有项目的第二种方法是可以的,即使这意味着您不会看到正确的统计信息来指示写入了多少行数据库以及有多少被忽略,因为它们已经存在。

如果您有选择,您可以在与您要写入的 table 相同的架构中创建另一个 table,然后您可以将文件中的所有行加载到另一个 table 在 spring 批处理作业的一个阶段,然后在下一阶段从 table 和 select 中仅查询目标中不存在的行 table.

您所谓的 skip(如 skip the items that are already present in the database)实际上是根据 Spring Batch 的术语过滤项目而不是跳过它们。 Spring 批处理中的跳过功能适用于无效项目(即那些在读取、处理或写入时会引发异常的项目)。

在您的用例中可以很好地工作的常用技术是通过执行“保存或更新”操作使项目编写器幂等。这消除了检查项目是否存在的需要。此外,这在失败的情况下很有用,因为您可以重新 运行 失败的作业而无需存储任何进度状态。