【发布时间】:2015-01-18 21:54:52
【问题描述】:
我有一个在 Spring Boot 中运行的 Spring Batch 项目,它运行良好。对于我的读者,我将 JdbcPagingItemReader 与 MySqlPagingQueryProvider 一起使用。
@Bean
public ItemReader<Person> reader(DataSource dataSource) {
MySqlPagingQueryProvider provider = new MySqlPagingQueryProvider()
provider.setSelectClause(ScoringConstants.SCORING_SELECT_STATEMENT)
provider.setFromClause(ScoringConstants.SCORING_FROM_CLAUSE)
provider.setSortKeys("p.id": Order.ASCENDING)
JdbcPagingItemReader<Person> reader = new JdbcPagingItemReader<Person>()
reader.setRowMapper(new PersonRowMapper())
reader.setDataSource(dataSource)
reader.setQueryProvider(provider)
//Setting these caused the exception
reader.setParameterValues(
startDate: new Date() - 31,
endDate: new Date()
)
reader.afterPropertiesSet()
return reader
}
但是,当我使用一些命名参数修改我的查询以替换以前硬编码的日期值并在阅读器上设置这些参数值时,如上所示,我在 second 页面读取时收到以下异常(第一页可以正常工作,因为分页查询提供程序没有使用 _id 参数):
org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter '_id': No value registered for key '_id'
at org.springframework.jdbc.core.namedparam.NamedParameterUtils.buildValueArray(NamedParameterUtils.java:336)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getPreparedStatementCreator(NamedParameterJdbcTemplate.java:374)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.query(NamedParameterJdbcTemplate.java:192)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.query(NamedParameterJdbcTemplate.java:199)
at org.springframework.batch.item.database.JdbcPagingItemReader.doReadPage(JdbcPagingItemReader.java:218)
at org.springframework.batch.item.database.AbstractPagingItemReader.doRead(AbstractPagingItemReader.java:108)
这里是一个 SQL 的例子,它默认没有 WHERE 子句。读取第二页时会自动创建一个:
select *, (select id from family f where date_created between :startDate and :endDate and f.creator_id = p.id) from person p
在第二页,sql被修改为以下,但是似乎没有提供_id的命名参数:
select *, (select id from family f where date_created between :startDate and :endDate and f.creator_id = p.id) from person p WHERE id > :_id
我想知道我是否不能将 MySqlPagingQueryProvider 排序键与 JdbcPagingItemReader 中设置的其他命名参数一起使用。如果不是,解决这个问题的最佳选择是什么?我需要能够为查询提供参数并对其进行分页(与使用光标相比)。谢谢!
【问题讨论】:
-
您似乎没有为新值设置 where 子句。您的配置示例中是否缺少此内容?
-
@MichaelMinella 感谢您的帮助。我在上面提供了一些 SQL。我的初始查询中没有 WHERE 子句,但是分页提供程序会在第一页之后自动添加一个。
-
我的意思是当你配置你的提供者时,你没有为 startDate 和 endDate 设置 where 子句,还是我遗漏了什么?
-
@MichaelMinella,请注意,这些不是在 where 子句中使用,而是在子选择中使用。您是否认为出于某种原因这会导致我在 _id 字段中遇到问题?我意识到我可以将其更改为连接而不是子选择并使用 where 子句,但我有许多额外的子选择不能成为连接,我为了减少混淆而删除了这些选择。该查询经过测试并且有效。就像我说的,第 1 页运行良好,直到第 2 页自动添加 WHERE 子句,命名的 _id 参数才被绑定。再次感谢您!
-
查看source 以及getParameterMap 函数的工作原理,它似乎涵盖了它。您是否有机会打开日志记录并查看“使用参数映射”的输出?
标签: java mysql spring spring-batch spring-boot