FlatFileItemReader从CSV文件中仅读取一行-Spring Batch

时间:2019-10-13 03:40:40

标签: spring spring-boot spring-batch flatfilereader

我正在创建一个Spring Batch Job,以将数据从给定的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;
}
}

1 个答案:

答案 0 :(得分:2)

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