Spring Batch导入CSV到数据库出现java.sql.Date类型不匹配错误求解决
错误原因
FlatFileItemReader默认使用的BeanWrapperFieldSetMapper没有内置字符串到java.sql.Date的类型转换器,CSV中读取到的日期字符串无法自动映射为DAOUser实体类中dateIntegration字段对应的java.sql.Date类型。
可行解决方案
方案1:为BeanWrapperFieldSetMapper注册日期类型转换器(推荐,改动最小)
直接修改BatchConfiguration类中reader方法的BeanWrapperFieldSetMapper配置,新增字符串转java.sql.Date的转换器即可,修改后的reader方法代码如下:
// 需额外引入转换服务依赖 import org.springframework.core.convert.support.DefaultConversionService; @Bean public FlatFileItemReader<DAOUser> reader() { FlatFileItemReader<DAOUser> reader = new FlatFileItemReader<>(); reader.setResource(new ClassPathResource("users.csv")); // 构造自定义类型转换服务,注册日期转换器 DefaultConversionService conversionService = new DefaultConversionService(); conversionService.addConverter(String.class, java.sql.Date.class, source -> { // CSV中日期格式为yyyy-MM-dd,直接符合java.sql.Date.valueOf的入参要求,trim处理字段前后空格 return java.sql.Date.valueOf(source.trim()); }); reader.setLineMapper(new DefaultLineMapper<DAOUser>() {{ setLineTokenizer(new DelimitedLineTokenizer() {{ setNames(new String[] { "dateIntegration","email","fullname","matricule","password","username" }); }}); setFieldSetMapper(new BeanWrapperFieldSetMapper<DAOUser>() {{ setTargetType(DAOUser.class); // 注入自定义转换服务 setConversionService(conversionService); }}); }}); return reader; }
方案2:在ItemProcessor中手动转换日期
先修改DAOUser实体类,将dateIntegration字段的类型暂时改为String,然后在UserItemProcessor的process方法中手动完成字符串到java.sql.Date的转换:
@Override public DAOUser process(final DAOUser person) throws Exception { final String password = bcryptEncoder.encode(person.getUsername()); // 手动转换日期格式 java.sql.Date dateIntegration = java.sql.Date.valueOf(person.getDateIntegration().trim()); final DAOUser transformedPerson = new DAOUser(dateIntegration,person.getEmail(),person.getFullname(),person.getMatricule(),password,person.getUsername()); log.info("Converting (" + person + ") into (" + transformedPerson + ")"); return transformedPerson; }
方案3:自定义FieldSetMapper实现字段映射
不使用通用的BeanWrapperFieldSetMapper,手动实现FieldSetMapper接口完成字段映射,日期部分自行转换:
// 需引入依赖 import org.springframework.batch.item.file.mapping.FieldSetMapper; import org.springframework.batch.item.file.transform.FieldSet; import org.springframework.validation.BindException; // 修改reader中setFieldSetMapper部分的代码 setFieldSetMapper(new FieldSetMapper<DAOUser>() { @Override public DAOUser mapFieldSet(FieldSet fieldSet) throws BindException { DAOUser user = new DAOUser(); user.setDateIntegration(java.sql.Date.valueOf(fieldSet.readString("dateIntegration").trim())); user.setEmail(fieldSet.readString("email").trim()); user.setFullname(fieldSet.readString("fullname").trim()); user.setMatricule(fieldSet.readString("matricule").trim()); user.setPassword(fieldSet.readString("password").trim()); user.setUsername(fieldSet.readString("username").trim()); return user; } });
内容的提问来源于stack exchange,提问作者houcem abidi
相关产品推荐
相关产品推荐

