简体   繁体   中英

how to read csv columns in different order in spring batch with spring boot

i am creating a spring batch application that reads the csv file and store in db.

i am able to read it and store in db only when i set column names in order.

its not working when i change the order in csv file.

My Objective:

My objective is that to read the file and store in db even if column names are not in order.

My CSv File looks like this:

id,name
1,xyz

Above order is working as expected. but if changes the order like below, it s not working. how can i solve it?

name,id
xyz,1

My Batch Configuration:

@Configuration
@EnableBatchProcessing
public class SpringBatchConfiguration {


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

        Step step = stepBuilderFactory.get("Loading-file")
                    .<BatchProcessEntity,BatchProcessEntity>chunk(100)
                    .reader(itemReader)
                    .processor(itemProcessor)
                    .writer(itemWriter)
                    .build();

        Job job=jobBuilderFactory.get("Csv")
                .incrementer(new RunIdIncrementer())
                .start(step).build();

        return job;

    }

    @Bean
    public FlatFileItemReader<BatchProcessEntity> flatFileItemReader(@Value("${input}") Resource resource) {

        FlatFileItemReader<BatchProcessEntity> flatFileItemReader=new FlatFileItemReader<>();

        flatFileItemReader.setResource(resource);
        flatFileItemReader.setName("Loading Csv File");
        flatFileItemReader.setLinesToSkip(1);
        flatFileItemReader.setLineMapper(lineMapper());

        return flatFileItemReader;

    }

    @Bean
    public LineMapper<BatchProcessEntity> lineMapper() {

        DefaultLineMapper<BatchProcessEntity> defLineMapper=new DefaultLineMapper<>();

        DelimitedLineTokenizer delimitedLineTokenizer=new DelimitedLineTokenizer();
        delimitedLineTokenizer.setDelimiter(",");
        delimitedLineTokenizer.setStrict(true);
        delimitedLineTokenizer.setNames(new String[] {"id","name"});


        BeanWrapperFieldSetMapper<BatchProcessEntity> beanWrapperFieldSetMapper=new BeanWrapperFieldSetMapper<>();
        beanWrapperFieldSetMapper.setTargetType(BatchProcessEntity.class);


        defLineMapper.setLineTokenizer(delimitedLineTokenizer);
        defLineMapper.setFieldSetMapper(beanWrapperFieldSetMapper);

        return defLineMapper;
    }
}

My Entity:

@Entity
@Table(name="springbatchprocess")
@Data
public class BatchProcessEntity {

@Id
Integer id;

@Column(name="name")
String eName;

@Column(name="address")
String eAddress;

@Column(name="salary")
String eSalary;

@Column(name="dept")
String eDept;

@Column(name="status")
Integer eStatus;

@Column(name="date")
Date date;

}

Above code is working fine only when i set columns in order as defined in code. when i change the order, its not working?

how can i solve it?

You need to write a custom mapper to do this. There is an example of one provided here in this tutorial:

https://www.baeldung.com/introduction-to-spring-batch

It'd be something like this:

public class BatchProcessFieldSetMapper implements FieldSetMapper<BatchProcessEntity> {

    public BatchProcessEntity mapFieldSet(FieldSet fieldSet) throws BindException {

        BatchProcessEntity batchProcessEntity = new BatchProcessEntity();

        batchProcessEntity.setEAddress(fieldSet.readString("address"));

        //...etc

        return batchProcessEntity;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM