首页 文章

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

提问于
浏览
3

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

  • 需要从数据库中读取一些元数据 .

  • 基于此元数据,我需要阅读一些文件 .

  • 经过一些处理后,需要将这些值从文件写入数据库 .

我的疑问如下:

一个 . 对于第一个要求,我需要将整个结果集映射到单个对象,其中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,在 Spring 季批次中,只有一个读者,没有作家就不能有一个步骤 . 因此,我不能在工作的不同步骤中召唤另一组读者 . 那么,如何一步调用多个读卡器?

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

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

1 回答

  • 1

    我建议如下

    High Level Design:

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

    • Reader它将获得属于Person的Pet列表 . 注意:Reader将仅返回特定于Person的Pet列表 .

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

    • Writer根据您的要求写入DB .

    Low Level Code snippet:

    • 分区

    公共类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;
    }
    

    }

    • 读者
    <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>
    

    public class PetByPersonIdRowMapper实现RowMapper <PersonPetDetails> {
    @覆盖
    public BillingFeeConfigEntity mapRow(ResultSet rs,int rowNum)抛出SQLException {
    PersonPetDetails record = new PersonPetDetails();

    record.setPersonId(rs.getLong( “PERSONID”));
    record.setPetId(rs.getLong( “petid”);
    ...
    ...
    }

    • 处理器您可以继续处理每个PersonPetDetails对象 .

相关问题