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

使用Spring Batch读取不同类型CSV文件的技术求助

Spring Batch多CSV文件读取与入库实现方案

1. 用MultiResourceItemReader批量读取多文件

这是Spring Batch官方推荐的多文件读取方式,它能遍历指定目录下的多个文件,逐个交给内部的FlatFileItemReader处理。

配置示例

@Bean
public MultiResourceItemReader<YourDto> multiResourceItemReader() {
    MultiResourceItemReader<YourDto> reader = new MultiResourceItemReader<>();
    // 指定文件路径,支持通配符,比如classpath:csv/*.csv 或者 file:/data/csv/*.csv
    reader.setResources(new PathMatchingResourcePatternResolver().getResources("file:/your/csv/path/*.csv"));
    // 设置内部的单个文件读取器
    reader.setDelegate(singleFlatFileItemReader());
    // 可选:设置是否严格匹配,找不到文件时是否报错
    reader.setStrict(false);
    return reader;
}

// 单个CSV文件的读取器(根据你的DTO调整字段映射)
@Bean
public FlatFileItemReader<YourDto> singleFlatFileItemReader() {
    FlatFileItemReader<YourDto> reader = new FlatFileItemReader<>();
    reader.setLineMapper(new DefaultLineMapper<YourDto>() {{
        setLineTokenizer(new DelimitedLineTokenizer() {{
            setNames("field1", "field2", "field3"); // CSV列名
        }});
        setFieldSetMapper(new BeanWrapperFieldSetMapper<YourDto>() {{
            setTargetType(YourDto.class);
        }});
    }});
    // 跳过表头
    reader.setLinesToSkip(1);
    return reader;
}

2. 处理不同格式的CSV文件

如果CSV字段结构不一致,无法共用一个FlatFileItemReader,可以用以下两种方案:

方案A:按文件类型拆分Job为多个Step

如果能通过文件名区分类型(比如user_*.csv、order_*.csv),给每种文件单独配置Step,每个Step用专属的MultiResourceItemReader、处理器和写入器:

@Bean
public Job multiCsvProcessingJob(JobBuilderFactory jobBuilderFactory,
                                 Step userCsvStep, Step orderCsvStep) {
    return jobBuilderFactory.get("multiCsvProcessingJob")
            .start(userCsvStep)
            .next(orderCsvStep)
            .build();
}

// 用户CSV的Step
@Bean
public Step userCsvStep(StepBuilderFactory stepBuilderFactory,
                        MultiResourceItemReader<UserDto> userReader,
                        UserItemProcessor userProcessor,
                        JdbcBatchItemWriter<UserDto> userWriter) {
    return stepBuilderFactory.get("userCsvStep")
            .<UserDto, User>chunk(100)
            .reader(userReader)
            .processor(userProcessor)
            .writer(userWriter)
            .build();
}

// 订单CSV的Step同理,替换对应的Reader/Processor/Writer即可

方案B:用ClassifierCompositeItemReader动态路由

如果文件名无法区分,需要根据文件内容判断类型,可以用ClassifierCompositeItemReader,先读取一行判断类型,再交给对应的Reader处理:

@Bean
public ClassifierCompositeItemReader<Object> compositeReader() {
    ClassifierCompositeItemReader<Object> reader = new ClassifierCompositeItemReader<>();
    // 自定义Classifier,根据读取的行判断文件类型,返回对应的ItemReader
    reader.setClassifier(new Classifier<String, ItemReader<?>>() {
        @Override
        public ItemReader<?> classify(String line) {
            // 示例:根据列数判断文件类型
            if (line.split(",").length == 3) {
                return userFlatFileItemReader();
            } else if (line.split(",").length == 5) {
                return orderFlatFileItemReader();
            }
            throw new IllegalArgumentException("Unknown CSV format: " + line);
        }
    });
    return reader;
}

3. 写入数据库

用Spring Batch的JdbcBatchItemWriter实现批量入库,示例如下:

@Bean
public JdbcBatchItemWriter<UserDto> userWriter(DataSource dataSource) {
    JdbcBatchItemWriter<UserDto> writer = new JdbcBatchItemWriter<>();
    writer.setDataSource(dataSource);
    writer.setSql("INSERT INTO user (field1, field2, field3) VALUES (:field1, :field2, :field3)");
    writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
    // 可选:设置批量更新大小
    writer.setBatchSize(100);
    return writer;
}

注意事项

  • 每个FlatFileItemReader要正确配置字段映射和表头跳过逻辑
  • 处理大文件时,调整chunk大小(建议100-1000)平衡性能与内存占用
  • 可配置SkipPolicy跳过错误行,或用RetryTemplate处理读取重试
  • MultiResourceItemReader会自动遍历所有匹配资源,无需手动循环

内容的提问来源于stack exchange,提问作者geeta gonchala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:40:29