我正在读取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();
}
}