【问题标题】:Dynamic SQL query with JdbcCursorItemReader使用 JdbcCursorItemReader 进行动态 SQL 查询
【发布时间】:2017-03-20 17:17:23
【问题描述】:

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

select * from history where employee_id = ?

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

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

【问题讨论】:

标签: java spring spring-batch


【解决方案1】:

首先,我不建议您这样做。理论上,几乎总是在实践中,打开单个游标比每次单独查询要高效得多。

“更好”的方法是将 ID 列表插入到暂存/驱动表中(通常是在较早的步骤中,每当您从原始来源获得该 ID 列表时),然后将您的查询更改为:

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

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

select * from history where employee_id in ( ? ) 

并向其传递 ID 列表(此处要小心,因为某些数据库会限制查询中的参数数量)。如果您的列表威胁要超过该限制,您需要打开一个新光标,有效地在列表上分页。

【讨论】:

  • 谢谢。该列表包含大约 200000 条记录 - 所以“IN”不起作用。我可以改用 JOIN。
  • 绝对加入。它的性能比将数据拉回来再次查询要好得多,并且会减少不必要的 I/O。
猜你喜欢
  • 2014-10-14
  • 1970-01-01
  • 2021-09-20
  • 1970-01-01
  • 2014-06-28
  • 2017-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多