1

我正在创建一个 Spring Batch 作业,以将数据从给定的 CSV 文件填充到数据库表中。我创建了一个自定义的 FlatFileItemReader。我的问题是 read() 方法只被调用一次,所以只有我的 CSV 文件的第一行被插入到数据库中。

@Configuration
@EnableBatchProcessing 
public class SpringBatchConfig {

private MultipartFile[] files;

@Bean
public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory,
        ItemReader<MyModelEntity> itemReader,
        ItemWriter<MyModelEntity> itemWriter) {

    Step step = stepBuilderFactory.get("Load-CSV-file_STP")
            .<MyModelEntity, MyModelEntity > chunk(12)
            .reader(itemReader)
            .writer(itemWriter).build();

    return jobBuilderFactory.get("Load-CSV-Files").
            incrementer(new RunIdIncrementer()) /
            .start(step) 
            .build();
}
 @Bean
  ItemReader<MyModelEntity> myModelCsvReader() throws Exception {
        return new MyModelCsvReader();
    }

 }

myModelCsvReader

@Component
@StepScope
public class MyModelCsvReader implements   ItemReader<MyModelEntity>{


@Value("#{jobParameters['SDH']}")
private String sdhPath;

private  boolean batchJobState= false;

@Autowired 
MyModelFieldSetMapper myModelFieldSetMapper;

public LineMapper<MyModelEntity> lineMapper() throws Exception {
    DefaultLineMapper<MyModelEntity> defaultLineMapper = new 
    DefaultLineMapper<MyModelEntity>();
    DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();

    lineTokenizer.setDelimiter(",");
    lineTokenizer.setStrict(false);  
    lineTokenizer.setNames(new String[] 
      {
      "clientId","ddId","institName","progName",
      "qual","startDate","endDate","eType", "country","comments"
      });

     defaultLineMapper.setLineTokenizer(lineTokenizer);
     defaultLineMapper.setFieldSetMapper(myModelFieldSetMapper);
    return defaultLineMapper;}

@Override
public   MyModelEntity  read()
        throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
     //if(!batchJobState )
    {
    FlatFileItemReader<MyModelEntity> flatFileItemReader = new 
    FlatFileItemReader<MyModelEntity>();
    flatFileItemReader.setMaxItemCount(2000);
    flatFileItemReader.setResource(new UrlResource("file:\\"+sdhPath));
    flatFileItemReader.setName("CSV-Reader");
    flatFileItemReader.setLinesToSkip(1);
    flatFileItemReader.setLineMapper(lineMapper());
    flatFileItemReader.open(new ExecutionContext());         
    batchJobState=true; 
    return flatFileItemReader.read();

    }
    // return null;
}
}

FieldSetMapper 实现

 @Component
public class MyModelFieldSetMapper  implements FieldSetMapper<MyModelEntity>  {

//private SiteService siteService =BeanUtil.getBean(SiteServiceImpl.class);

 @Autowired 
 private SiteService siteService;

@Override
public MyModelEntity mapFieldSet(FieldSet fieldSet ) throws BindException {
    if(fieldSet == null){
           return null;
       }
    MyModelEntity educationHistory = new MyModelEntity();
    // setting MyModelAttributes Values 
    return myModel; 
}
}

欢迎任何贡献。谢谢 // 扩展 FlatFileItemReader 后的读者

@Component
@StepScope
public class CustomUserItemReader  extends FlatFileItemReader<User> {
@Value("#{jobParameters['UserCSVPath']}")
private String UserCSVPath;
private boolean batchJobState;

public   CustomUserItemReader() throws Exception {
    super();

    setResource(new UrlResource("file:\\"+UserCSVPath));
    setLineMapper(lineMapper());
    afterPropertiesSet();
    setStrict(false);

}

 public LineMapper<User> lineMapper() throws Exception {
 DefaultLineMapper<User> defaultLineMapper = 
    new DefaultLineMapper<User>();
    DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();

    lineTokenizer.setDelimiter(",");
    lineTokenizer.setStrict(false);
    lineTokenizer.setNames(new String[]{"name", "dept", 
   "salary","endDate"});
    defaultLineMapper.setLineTokenizer(lineTokenizer);
    defaultLineMapper.setFieldSetMapper(new CustomUserFieldSetMapper());
    //defaultLineMapper.setFieldSetMapper(fieldSetMapper);
    return defaultLineMapper;}
 @Override
 public   User  read()
        throws Exception, UnexpectedInputException, ParseException, 
   NonTransientResourceException {
    //if(!batchJobState )
    {
    flatFileItemReader).size())
      //  flatFileItemReader.setMaxItemCount(2000);
        this.setResource(new UrlResource("file:\\"+UserCSVPath));
        this.setName("CSV-Reader");
        this.setLinesToSkip(1);
        //flatFileItemReader.setLineMapper(lineMapper());
        this.open(new ExecutionContext());
        User e = this.read();
        batchJobState = true;
        return e ;

    }
    // return null;
}

public
String getUserCSVPath() {
    return UserCSVPath;
}

public
void setUserCSVPath(String userCSVPath) {
    UserCSVPath = userCSVPath;
}
}
4

1 回答 1

2

感谢您的所有建议,即使我已经实现了 ItemReader<>。我通过将 FlatFileItemReader 的实例化从 read() 方法移出来解决了这个问题。这是在每个循环中创建一个新的 FlatFileItemReader 并只读取每个创建的对象的第一行。谢谢

于 2019-10-13T21:49:06.710 回答