使用Spring批处理读取CSV文件并根据第一个字段映射到Domain对象,然后将其相应地插入数据库中

时间:2019-07-25 12:32:44

标签: spring-batch

我正在读取Spring批处理的CSV文件,我想读取每一行,并根据报告中的第一个字段确定我也想映射哪个对象

我有两个对象:订单明细和项目明细,因此,如果第一个字段是ORD,则我映射到订单明细并在DB的订单明细表中插入;如果第一个字段是DET,则我映射到项目明细DTO,然后插入数据库中的商品明细表。

有人可以指导我如何做到吗?

我搜索了不同的解决方案,但无法获得所需的信息,不确定PatternMatchingCompositeLineMapper<T>是否是解决此问题的方法。

这是csv文件格式:

ORD,02013872,12345,,P,,,HYD800,,,,,
DET,1.0,100,5.0,,31Jan2017,,,,,
DET,2.0,120001,10.0,,25Jan2017,,,,,
ORD,02013872,12345,,P,,,HYD800,,,,,
DET,1.0,100,5.0,,31Jan2017,,,,,
DET,2.0,120001,10.0,,25Jan2017,,,,,
ORD,02013872,12345,,P,,,HYD800,,,,,
DET,1.0,100,5.0,,31Jan2017,,,,,
DET,2.0,120001,10.0,,25Jan2017,,,,,

这是我到目前为止的代码:

@Configuration
@EnableBatchProcessing
public class BatchConfig {

@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;

@Bean
public Step sampleStep(JdbcBatchItemWriter<OrderDetail> writer) throws Exception {

    return stepBuilderFactory.get("sampleStep")
            .<OrderDetail,OrderDetail>chunk(5)
            .reader(reader(null))
            .writer(writer)
            .build();
}

@Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step sampleStep) {
    return jobBuilderFactory.get("orderJob")
            .incrementer(new RunIdIncrementer())
            .listener(listener)
            .flow(sampleStep)
            .end()
            .build();
}

@Bean
@StepScope
public JdbcBatchItemWriter<OrderDetail> writer(DataSource dataSource,@Value("#{jobParameters[file_path]}") String filePath) {

    final FileSystemResource fileResource = new FileSystemResource(filePath);

    System.out.println("Branch code is : " + fileResource.getFilename().substring(5,8)); //getting the branch code from the path to insert it in table order details
    String branchCode = fileResource.getFilename().substring(5,8);

    return new JdbcBatchItemWriterBuilder<OrderDetail>()
             .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
            .sql("INSERT INTO order_detail (ord, branch_code, eiclient_number, client_order_number, consigneep, payment_terms, earliest_ship_date, latest_ship_date, consignee_code, bill_to_code, third_party_bill_to_customer_no, preferred_carrier, usd1, usd2) " +
                    "VALUES (:ord, '"+branchCode+"', :eiclientNumber, :clientOrderNumber, :consigneeP, :paymentTerms, :earliestShipDate, :latestShipDate, :consigneeCode, :billToCode, :thirdPartyBillToCustomerNo, :preferredCarrier, :usd1, :usd2)")
           /* .sql("INSERT INTO item_detail (ord_no, branch_code, detail, line_number, sku_number, qty, lot_no, receipt_po, usd1, usd2, usd3, usd4) " +
                    "VALUES (:ordNo, '"+branchCode+"', :detail, :lineNumber, :skuNumber, :qty, :lotNo, :receiptPo, :usd1, :usd2, :usd3, :usd4)")
*/
            .dataSource(dataSource)
            .build();

}

@Bean
@StepScope
public FlatFileItemReader reader(@Value("#{jobParameters[file_path]}") String filePath) throws Exception {

    final FileSystemResource fileResource = new FileSystemResource(filePath);
    return new FlatFileItemReaderBuilder()
            .name("ordersItemReader")
            .resource(fileResource)
            .lineMapper(orderLineMapper())
            /*.delimited()
            .names(new String[]{"ord", "branchCode", "eiclientNumber", "clientOrderNumber", "consigneeP", "paymentTerms", "earliestShipDate", "latestShipDate", "consigneeCode", "billToCode", "thirdPartyBillToCustomerNo"})
            .fieldSetMapper(new BeanWrapperFieldSetMapper<OrderDetail>() {{
                setTargetType(OrderDetail.class);
            }})*/
            .build();
}


@Bean
public LineMapper orderLineMapper() throws Exception {

    PatternMatchingCompositeLineMapper mapper = new PatternMatchingCompositeLineMapper();

    Map<String, LineTokenizer> tokenizers = new HashMap<String, LineTokenizer>();
    tokenizers.put("ORD*",orderTokenizer() );
    //tokenizers.put("DET*",orderItemTokenizer());
    mapper.setTokenizers(tokenizers);

    Map<String, FieldSetMapper> mappers = new HashMap<String, FieldSetMapper>();
    mappers.put("ORD*", orderFieldSetMapper());
   // mappers.put("DET*", orderLineFieldSetMapper());

    mapper.setFieldSetMappers(mappers);

    return mapper;

}


@Bean
public LineTokenizer orderTokenizer() {
    DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(",");
    tokenizer.setNames(new String[] { "ord", "eiclientNumber", "clientOrderNumber", "consigneeP", "paymentTerms", "earliestShipDate", "latestShipDate", "consigneeCode", "billToCode", "thirdPartyBillToCustomerNo", "preferredCarrier", "usd1","usd2"});
    return tokenizer;
}

@Bean
public LineTokenizer orderItemTokenizer() {
    DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(",");
    tokenizer.setNames(new String[] { "ordNo", "detail", "lineNumber", "skuNumber", "qty", "lotNo", "receiptPo", "usd1", "usd2", "usd3", "usd4"});
    return tokenizer;
}

@Bean
public FieldSetMapper<OrderDetail> orderFieldSetMapper() throws Exception {
    BeanWrapperFieldSetMapper<OrderDetail> mapper =
            new BeanWrapperFieldSetMapper<OrderDetail>();

    mapper.setPrototypeBeanName("orderDetail");
    mapper.afterPropertiesSet();
    return mapper;
}


@Bean
@Scope("prototype")
public OrderDetail orderDetail() {
    return new OrderDetail();
}

}

0 个答案:

没有答案