使用JdbcCursorItemReader进行动态SQL查询

时间:2017-03-20 17:17:24

标签: java spring spring-batch

我正在使用java配置(spring-boot)进行spring批处理。我有一个Employee ID列表,对于每个Id,我需要运行一个查询(如下所示),然后处理数据。

select * from history where employee_id = ?

我知道我们可以使用reader.setPreparedStatementSetter在上面的SQL中动态设置参数。但是,我不确定如何为列表中的每个员工ID重复批处理。即使我将reader()标记为@StepScope,读者也只被调用一次。 (即),批次只运行一次。任何帮助表示赞赏。

    List employeeIds = new ArrayList();
    employeeIds.add(1);
    employeeIds.add(2);

    @Bean
    @StepScope
    public ItemReader<History> reader() {
        JdbcCursorItemReader<History> databaseReader = new JdbcCursorItemReader<>();
        databaseReader.setSql("select * from history where employee_id = ?");
        databaseReader.setPreparedStatementSetter(..);
        ....

        return databaseReader;
    }


    @Bean
    public Step step(StepBuilder stepBuilder){
        return stepBuilderFactory.get("sample").
                .reader(reader())
                .processor(processor())
                .writer(writer())
                .build();
    }

1 个答案:

答案 0 :(得分:2)

首先,我不建议你这样做。从理论上讲,几乎总是在实践中,打开单个游标比每次单独查询更有效。

“更好”的方法是将ID列表插入到临时/驱动表中(通常在前面的步骤中,只要从原始源获取ID列表),然后将查询更改为:

select * from history where employee_id in (select id from driving_table)

或者,您可以至少将查询更改为:

select * from history where employee_id in ( ? ) 

并将ID列表传递给它(这里要小心,因为某些数据库会限制查询中的参数数量)。如果您的列表有可能超过该限制,则需要打开一个新光标,有效地对列表进行分页。