Spring Batch:一步完成多个项目读者

时间:2016-09-07 15:34:12

标签: java spring-batch

我是春季批次的新手。我需要在春季批次中完成的任务如下:

  1. 需要从数据库中读取一些元数据。
  2. 根据此元数据,我需要阅读一些文件。
  3. 经过一些处理后,需要将这些值从文件写入数据库。
  4. 我的查询如下:

    一个。对于第一个要求,我需要将整个结果集映射到单个对象,其中Person相关数据在1个表中,而Pets相关数据在另一个表中并由person id连接。

    public class PersonPetDetails {
    
        private String personName;
        private String personAddr;
    
        private int personAge;
    
        private List<Pet> pets;
    

    为此,我编写了一个自定义Item阅读器,它扩展了JdbcCursorItemReader。

    public class CustomJDBCCusrorItemReader<T> extends JdbcCursorItemReader<T> {
    
        private ResultSetExtractor<T> resultSetExtractor;
    
    
        public void setResultSetExtractor(ResultSetExtractor<T> resultSetExtractor) {
            this.resultSetExtractor = resultSetExtractor;
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            setVerifyCursorPosition(false);
            Assert.notNull(getDataSource(), "DataSource must be provided");
            Assert.notNull(getSql(), "The SQL query must be provided");
            Assert.notNull(resultSetExtractor, "ResultSetExtractor must be provided");
        }
    
    
        @Override
        protected T readCursor(ResultSet rs, int currentRow) throws SQLException {      
            return resultSetExtractor.extractData(rs);
        }
    }
    

    这是达到我要求的正确方法吗?或者有更好的方法吗?

    湾AFAIK,在春季批次中,只有一个读者,没有作家,就不可能迈出一步。因此,我不能在工作的不同步骤中召唤另一组读者。那么,如何在一个步骤中调用多个读者呢?

    ℃。此外,根据某些条件,我可能需要调用第三组Reader。我怎样才能有条不紊地给读者打电话?

    感谢您浏览我的帖子。我知道它很长。任何帮助深表感谢。此外,我想一个示例代码片段将帮助我更好地理解这一点。 :)

1 个答案:

答案 0 :(得分:1)

我建议如下

高级设计:

  1. 分区 它将处理人员名单。注意:此时没有提取宠物数据。

  2. 阅读器 它将获得属于Person的Pet列表。注意:Reader将仅返回特定于某人的Pet列表。

  3. 处理器 基于宠物人,您将根据您的要求进行处理。

  4. 作家 根据您的要求写入DB。

  5. 低级代码段

    1. 分区
    2. public class PetPersonPartitioner实现了Partitioner {

      @Autowired
      private PersonDAO personDAO;
      
      @Override
      public Map<String, ExecutionContext> partition(int gridSize) {
      
          Map<String, ExecutionContext> queue = new HashMap<String, ExecutionContext>();
      
          List<Person> personList = this.personDAO.getAllPersons();
          for (Person person : personList) {
      
              ExecutionContext ec = new ExecutionContext();
              ec.put("person", person);
              ec.put("personId", person.getId());
      
              queue.put(person.getId(), ec);
          }
      
          return queue;
      }
      

      }

      1. 阅读器

                                                

        <bean id="petByPersonIdRowMapper" class="yourpackage.PetByPersonIdRowMapper" />
        
        <bean id="petByPesonIdStatementSetter" scope="step"
              class="org.springframework.batch.core.resource.ListPreparedStatementSetter">
            <property name="parameters">
                <list>
                    <value>#{stepExecutionContext['personId']}</value>
                </list>
            </property>
        </bean>
        
      2. public class PetByPersonIdRowMapper implements RowMapper<PersonPetDetails> {
            @Override
            public BillingFeeConfigEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
                PersonPetDetails record = new PersonPetDetails();
        
                record.setPersonId(rs.getLong("personId"));
              record.setPetId(rs.getLong("petid");
              ...
              ...
        }
        
        1. 处理器 您可以继续处理每个PersonPetDetails对象。