You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Batch处理器中执行查询实现字段校验,附现有配置代码

Spring Batch处理器内执行查询做字段校验的实现方案

你可以直接在现有处理器的基础上做如下改造,无需调整其他已定义的Reader、Writer、Step逻辑:


实现步骤

  • 第一步:给处理器注入查询依赖
    你已经将CaricoDTOItemProcessorStep1声明为Spring管理的Bean,直接在类中注入所需的数据库操作组件即可,推荐直接注入JdbcTemplate,也可以注入你自行封装的DAO、Mapper、Repository等持久层组件。改造后的处理器类示例如下:
public class CaricoDTOItemProcessorStep1 implements ItemProcessor<CaricoDTO, CaricoDTO> {

    private String fileName;
    private static final Logger log = LoggerFactory.getLogger(CaricoDTOItemProcessorStep1.class);
    // 注入JdbcTemplate,Spring会自动根据容器中的DataSource完成装配
    @Autowired
    private JdbcTemplate jdbcTemplate;

    // 可选配置:如果校验规则固定,可提前把校验数据加载到本地缓存大幅提升性能
    private Set<String> validCodeSet;
    @PostConstruct
    public void initValidCache() {
        // Bean初始化时一次性查询所有合法的校验值存入缓存,避免每条数据都查库
        validCodeSet = new HashSet<>(jdbcTemplate.queryForList("select code from 你的校验码表", String.class));
    }
    
    @Override
    public CaricoDTO process(CaricoDTO carico) throws Exception {
        // 保留原有逻辑
        carico.setDataCaricamento(new Date(System.currentTimeMillis()));
        carico.setFileName(carico.getResource().getFilename());

        // 新增字段校验逻辑
        // 示例1:直接查库校验,适合校验规则不固定、缓存命中率低的场景
        Integer existCount = jdbcTemplate.queryForObject("select count(1) from 你的业务表 where 校验字段 = ?", Integer.class, carico.get你要校验的字段());
        if(existCount == null || existCount == 0) {
            // 校验不通过处理:返回null即可让Spring Batch跳过该条数据不写入数据库,也可以打印日志记录异常
            log.warn("数据ID={}校验不通过,已跳过", carico.getId());
            return null;
        }

        // 示例2:用预加载的缓存校验,性能更高,适合校验规则固定的场景
        if(!validCodeSet.contains(carico.getCode())) {
            log.warn("数据编码={}不合法,已跳过", carico.getCode());
            return null;
        }

        // 校验通过返回对象进入Writer执行写入
        return carico;
    }
    // 原有get/set方法保留
    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
}
  • 第二步:可选配置,校验异常容错处理
    如果希望校验不通过时抛自定义异常而非返回null,同时统计跳过的异常数据,可以在Step定义时添加skip配置:
@Bean
public Step step1(JdbcBatchItemWriter<CaricoDTO> step1Writer) {
    return stepBuilderFactory.get("step1").<CaricoDTO, CaricoDTO>chunk(10)
            .reader(multiResourceItemReader())
            .processor(processorStep1())
            .writer(step1Writer)
            // 新增容错配置:遇到自定义的校验异常时跳过,最多允许跳过100条异常数据
            .faultTolerant()
            .skip(ValidationException.class)
            .skipLimit(100)
            .build();
}

注意事项

  • 如果你的Step配置了多线程执行,本地缓存需要使用线程安全的集合类如ConcurrentHashMap、CopyOnWriteArraySet等
  • 数据量极大的场景下,不建议每条数据都单独查库,优先采用预加载缓存、批量校验的方案优化性能
  • 校验逻辑不要单独开启事务,事务控制统一在Chunk层面处理即可

内容的提问来源于stack exchange,提问作者Rosalba Marotta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 11:15:05