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

Spring Batch字符串日期转java.sql.Date入库类型不匹配问题

Spring Batch 字符串日期转java.sql.Date类型不匹配问题解决

我之前也碰到过一模一样的问题!Spring Batch默认的属性绑定器没法自动把字符串格式的日期转换成java.sql.Date类型,所以才会抛出这个typeMismatch错误。给你几个靠谱的解决办法,挑适合你项目的来用:

方法1:在ItemProcessor里手动转换(最直接)

Spring Batch的ItemProcessor本来就是用来做数据转换、清洗的,咱们可以在这里把文件模型里的字符串日期转成数据库实体需要的java.sql.Date:

@Component
public class SkuDataProcessor implements ItemProcessor<VSOGOutOfStockSkuDataForBatchJob, VSOGOutOfStockSkuData> {
    // 注意这里的日期格式要和文件里的完全匹配,你的是yyyy-MM-dd
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Override
    public VSOGOutOfStockSkuData process(VSOGOutOfStockSkuDataForBatchJob fileModel) throws Exception {
        VSOGOutOfStockSkuData dbEntity = new VSOGOutOfStockSkuData();
        
        // 复制其他字段,比如skuId、stockStatus这些...
        dbEntity.setSkuId(fileModel.getSkuId());
        dbEntity.setStockStatus(fileModel.getStockStatus());
        
        // 处理日期转换
        if (fileModel.getPlaceDate() != null && !fileModel.getPlaceDate().isBlank()) {
            LocalDate localDate = LocalDate.parse(fileModel.getPlaceDate(), DATE_FORMATTER);
            dbEntity.setPlaceDate(java.sql.Date.valueOf(localDate));
        }
        
        return dbEntity;
    }
}

然后在你的步骤配置里把这个处理器加上就行,确保数据在写入数据库前完成转换。

方法2:自定义Spring转换器,让框架自动处理

如果不想在处理器里写硬编码的转换逻辑,可以自定义一个字符串转java.sql.Date的转换器,注册到Spring的ConversionService里,这样框架会自动帮你完成绑定:

第一步:写转换器类

@Component
public class StringToSqlDateConverter implements Converter<String, java.sql.Date> {
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Override
    public java.sql.Date convert(String dateStr) {
        if (dateStr == null || dateStr.isBlank()) {
            return null;
        }
        LocalDate localDate = LocalDate.parse(dateStr, DATE_FORMATTER);
        return java.sql.Date.valueOf(localDate);
    }
}

第二步:注册转换器到ConversionService

在你的Batch配置类里,把这个转换器加入到默认的转换服务中,然后配置给FieldSetMapper:

@Configuration
public class BatchStepConfig {
    @Autowired
    private StringToSqlDateConverter dateConverter;

    @Bean
    public ConversionService batchConversionService() {
        DefaultConversionService conversionService = new DefaultConversionService();
        conversionService.addConverter(dateConverter);
        return conversionService;
    }

    // 配置FlatFileItemReader的时候,把转换服务设置给BeanWrapperFieldSetMapper
    @Bean
    public FlatFileItemReader<VSOGOutOfStockSkuDataForBatchJob> skuFileReader() {
        FlatFileItemReader<VSOGOutOfStockSkuDataForBatchJob> reader = new FlatFileItemReader<>();
        // 配置文件路径、分隔符等...
        reader.setResource(new FileSystemResource("your-local-file-path"));
        reader.setLineTokenizer(new DelimitedLineTokenizer() {{
            setNames("skuId", "placeDate", "stockStatus"); // 对应文件里的字段名
        }});

        // 设置带自定义转换服务的FieldSetMapper
        BeanWrapperFieldSetMapper<VSOGOutOfStockSkuDataForBatchJob> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
        fieldSetMapper.setTargetType(VSOGOutOfStockSkuDataForBatchJob.class);
        fieldSetMapper.setConversionService(batchConversionService());
        
        reader.setLineMapper(new DefaultLineMapper<>() {{
            setLineTokenizer(reader.getLineTokenizer());
            setFieldSetMapper(fieldSetMapper);
        }});

        return reader;
    }
}

这样配置后,Spring Batch在读取文件映射到模型类的时候,或者从模型转实体的时候,都会自动用咱们的转换器处理日期字段。

方法3:调整实体类字段类型(可选)

如果你的项目允许修改数据库实体类的字段类型,可以把java.sql.Date改成java.time.LocalDate(Java 8+推荐的日期类型),这样和文件里的字符串日期适配性更好,Spring也能自动处理转换(只要格式匹配)。修改后的数据库实体类字段:

@Entity
public class VSOGOutOfStockSkuData {
    // 其他字段...
    private LocalDate placeDate;

    // getter和setter...
}

对应的文件模型类也可以改成LocalDate类型,这样就不用额外写转换逻辑了,不过这个方法需要确保数据库字段也支持LocalDate(比如MySQL的DATE类型是兼容的)。


内容的提问来源于stack exchange,提问作者Sanjay Naik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:39:15