2016-08-18 137 views
2

作为Spring Batch的新手,我通过探索一些POC取得了很好的进展。我目前正在研究的一个POC是关于从csv文件读取数据并加载到具有父子关系的数据库表中的。弹簧批处理作家父子表数据批量加载

CSV文件现在包含客户和订单信息,如下所示。

  1. custname1,custaddress1,custzip1,orderdate11,ordervalue11,ordertax11
  2. custname1,custaddress1,custzip1,orderdate12,ordervalue12,ordertax12
  3. custname2,custaddress2,custzip2,orderdate21,ordervalue21,ordertax21
  4. custname2, custaddress2,custzip2,orderdate22,ordervalue22,ordertax22

这些数据将被加载到数据库表中客户,订单,其中CUSTID和的OrderId将自动摹由Oracle序列和表订单具有CustId作为外键维护1对多关系(1客户可以有多个订单)

FlatFileItemReader,FieldSetMapper,ItemWriter是我在这个POC中使用的接口,我正在使用JdbcTemplate用于数据库操作。

我有以下问题。请澄清。

1)如何设计我的Reader bean?

模型类Customer有它的成员,getters和setter方法。与模型类Order相同。

客户类(从CSV文件读取数据)是否包含Order类的成员以及相应的getter,setter方法以表示父子关系?

2)如何检索我正在使用sequence.nextval在INSERT sql中为客户创建它的主键?

3)如何从父数据批量加载存储所有主键,然后将它们用于子表数据加载中的外键?

谢谢。

回答

0

考虑在这种情况下将数据作为Hibernate实体持久化。如果你仍然想使用JdbcTemplate,这里有一些建议。这是我发现的一个很好的例子 - http://www.javaworld.com/article/2458888/spring-framework/open-source-java-projects-spring-batch.html

1)如何设计我的Reader bean?

读者应该只是将给定的行读入相应的单个bean(让我们称之为CustomerOrder)。在读者中不要试图映射到父子bean结构。

2)如何检索我正在使用sequence.nextval的INSERT sql for Customer目前在 内创建的主键?

使用SimpleJdbcInsert。在ItemWriter中,对于每个CustomerOrder bean,检查客户名是否已经存在(我假设每个客户都有唯一的名称和地址)。检查这个样本(注意:我还没有执行/编译它,它只是一个例证)

public class CustomerOrderWriter implements ItemWriter<CustomerOrder> 
{ 
    private static final String GET_CUSTOMER = "select * from CUSTOMER where name = ? and address =?"; 
    private static final String INSERT_CUSTOMER = "insert into CUSTOMER (name,address) values (?,?)"; 
    private static final String INSERT_ORDER = "insert into ORDER (customer_id, date, value, tax) values (?,?,?,?)"; 

    @Autowired 
    private JdbcTemplate jdbcTemplate; 

    @Override 
    public void write(List<? extends CustomerOrder> customerOrders) throws Exception 
    { 
     //Process Write for each CSV row 
     for(CustomerOrder custOrd : customerOrders) 
     { 
      //Check if a customer exists 
      List<Customer> custList = jdbcTemplate.query(GET_CUSTOMER, new Object[] {custOrd.getName(), custOrd.getAddress() }, new RowMapper<Customer>() { 
       @Override 
       public Customer mapRow(ResultSet resultSet, int rowNum) throws SQLException { 
        Customer c = new Customer(); 
        c.setId(resultSet.getInt(1)); 
        return c; 
       } 
      }); 

      //If customer already exists, just get the ID and insert the Order 
      if(custList.size() > 0) 
      { 
       //Since the customer is found, insert the Order table here with the customer ID. 
      } 
      else 
      { 
       //Insert the customer, using "SimpleJdbcInsert", get the newly inserted customer Id and then insert the Order table 
      } 
     } 
    } 
} 

3)如何存储所有从父数据批量加载主键和 然后使用他们的外键在子表中的数据加载?

如果按照答案2中的设计,则不需要这样做。

+0

Shankar, 感谢您的意见。是的,你上面提供的javaworld示例链接,我对此很熟悉。但是,每次在数据库中存在客户记录(在for循环中)时都要进行验证,这并不是我所期待的。我想插入带有自动生成值的客户记录(使用Oracle序列)作为主键;提取PK;用它在子表中插入相应的Order行。 请指导我如何使用JdbcTemplate方法完成。 谢谢。 – VenkatRam