JdbcPollingChannelAdapter只使用id - no bean进行更新

时间:2017-06-27 22:35:13

标签: spring spring-integration integration

我有以下bean定义:

@Bean
JdbcPollingChannelAdapter jdbcPollingChannelAdapter() {
    // Get all the pending jobs
    JdbcPollingChannelAdapter adapter = new JdbcPollingChannelAdapter(jdbcTemplate, "select id from poller_jobs where status = 'PENDING'");
    // Immediately mark them as running so the next jdbc poll doesn't re-process them
    adapter.setUpdateSql("update poller_jobs set status='RUNNING' where id in (:id)");
    adapter.setMaxRowsPerPoll(100);
    adapter.setRowMapper((r, i) -> r.getLong("id"));
    return adapter;
}

这会失败,因为行映射器只映射到long id,因此适配器不知道如何获取更新中所需的ID。任何人都知道如何做到这一点,而不需要select *并映射到一个完整的对象?这似乎比我真正需要的开销更多。

1 个答案:

答案 0 :(得分:1)

这对我有用:

<inbound-channel-adapter data-source="dataSource"
                             channel="target"
                             query="select id from item where status=2"
                             update="update item set status=10 where id in (:#root)"
                             update-per-row="true"
                             row-mapper="columnRowMapper"/>

    <beans:bean id="columnRowMapper" class="org.springframework.jdbc.core.SingleColumnRowMapper"/>

所以,第一个是(:#root)作为param占位符,因为默认的setUpdateSqlParameterSourceFactory()ExpressionEvaluatingSqlParameterSourceFactory,其中评估上下文的根对象是SELECT的结果,或者因为它位于update-per-row="true"的每一行ResultSet

 if (payload != null && this.updateSql != null) {
        if (this.updatePerRow) {
            for (Object row : payload) {
                executeUpdateQuery(row);
            }
        }
        else {
            executeUpdateQuery(payload);
        }
    }

因此,您在配置中需要的是这两行代码:

 adapter.setUpdateSql("update poller_jobs set status='RUNNING' where id in (:#root)");
 adapter.setUpdatePerRow(true);

SingleColumnRowMapperResultSet,BTW中的真正单列做了诀窍。