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

时间:2019-08-19 12:44:08

标签: spring spring-batch

如果csv文件只有以ORD开头的行,我可以读取并插入DB中,但是如果文件显示如下,并混合了不同的行,我可以进行映射,但是问题是我使用的是块的对象类型,因为它需要一种类型的类。

我想映射每行,然后根据前三个字符相应地插入数据库,如果该行以ORD开头,则插入Order表,如果以DET开头,然后插入Detail表,下面的代码显示了我在哪里到目前为止,您有什么需要帮助的吗?

请注意,文件结构始终显示订单,然后显示与此订单相关的项目。

这是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,,,,,

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

@Entity
public class OrderDetail {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String branchCode;
private String ord;
private String eiclientNumber;
private String clientOrderNumber;
private String consigneeP;
private String paymentTerms;
private String earliestShipDate;
private String latestShipDate;
private String consigneeCode;
private String billToCode;
private String thirdPartyBillToCustomerNo;
private String preferredCarrier;
private String usd1;
private String usd2;

@ManyToMany(mappedBy = "orderDetails")
private Set<ItemDetail>  itemDetails = new HashSet<>();
}

@Entity
public class ItemDetail {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String branchCode;
private String ordNo;
private String detail;
private String lineNumber;
private String skuNumber;
private String qty;
private String lotNo;
private String receiptPo;
private String usd1;
private String usd2;
private String usd3;
private String usd4;


@ManyToMany
@JoinTable(name = "order_item", joinColumns = @JoinColumn(name = "item_id"), 
inverseJoinColumns = @JoinColumn(name = "order_id"))
private Set<OrderDetail> orderDetails = new HashSet<>();
}

@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 个答案:

没有答案