JdbcPollingChannelAdapter 更新仅使用 id -- 没有 bean

JdbcPollingChannelAdapter update using only the id -- no bean

我有以下 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 * 和映射到完整对象的情况下做到这一点?这似乎比我真正需要的开销要多。

这对我有用:

<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)作为参数占位符只是因为默认的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 中真正的单列有效,顺便说一句。