如果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();
}
}