У меня есть проект Spring Batch, работающий в Spring Boot, который работает отлично. Для моего читателя я использую 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
}
Однако, когда я изменил свой запрос с некоторыми именованными параметрами, чтобы заменить ранее жестко закодированные значения даты и установить эти значения параметров в средстве чтения, как показано выше, я получаю следующее исключение на прочитанной второй странице (первой page работает нормально, потому что параметр _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. Если нет, то какова наилучшая альтернатива решению этой проблемы? Мне нужно иметь возможность предоставлять параметры для запроса, а также отображать его (по сравнению с использованием курсора). Благодарю вас!