Использование SpringBatch JdbcCursorItemReader с List в качестве NamedParameters - PullRequest
0 голосов
/ 20 февраля 2019

Я использую приведенное ниже определение bean-компонента для настройки считывателя для чтения некоторых данных из таблицы базы данных в проекте Spring Batch.Он использует именованный параметр в SQL.Я передаю java.util.List в качестве параметра.Тем не менее я получаю сообщение об ошибке типа недопустимого столбца при попытке запустить SQL.

Если я просто жестко кодирую одно единственное значение (namedParameters.put("keys", "138219");) вместо передачи списка, это работает.

@Bean
public JdbcCursorItemReader<MyDTO> myReader() {
JdbcCursorItemReader<MyDTO> itemReader = new JdbcCursorItemReader<>();
itemReader.setDataSource(myDatasource);
itemReader.setRowMapper(return new RowMapper<MyDTO>() {
    @Override
    public MyDTO mapRow(ResultSet resultSet, int rowNum) throws SQLException {
       return toRetailSeasonalE3PromotionDTO(resultSet);
    }
};);


Map<String, Object> namedParameters = new HashMap<>();
List<Long> keys= //Some List
Map<String, List<Long>> singletonMap = Collections.singletonMap("keys", keys);
namedParameters.putAll(singletonMap);

itemReader.setSql(NamedParameterUtils.substituteNamedParameters("SELECT A FROM MYTABLE WHERE KEY IN (:keys)",new MapSqlParameterSource(namedParameters)));

ListPreparedStatementSetter listPreparedStatementSetter = new ListPreparedStatementSetter();
listPreparedStatementSetter.setParameters(
    Arrays.asList(NamedParameterUtils.buildValueArray("SELECT A FROM MYTABLE WHERE KEY IN (:keys)", namedParameters)));

itemReader.setPreparedStatementSetter(listPreparedStatementSetter);
return itemReader;
}

Я сослался пример кода здесь как ответ на один из вопросов , заданных - это то, что, кажется, работает, когда мы передаем одно значение.Тем не менее, моя проблема заключается в передаче списка вместо одного значения в параметре.Это где, кажется, не удается.

1 Ответ

0 голосов
/ 26 февраля 2019

ListPreparedStatementSetter не знает о типах параметров.Если параметр является массивом или коллекцией, он установит его в качестве первого заполнителя, оставив другие заполнители неустановленными.Отсюда и ошибка.В вашем примере, если List<Long> keys = Arrays.asList(1, 2), ваш SQL-оператор будет:

SELECT A FROM MYTABLE WHERE KEY IN (?, ?)

Если вы передадите singletonMap в ListPreparedStatementSetter, он установит значение keys (котороенаберите List) для первого заполнителя и все.Второй заполнитель все равно не будет установлен, и подготовка оператора не удастся.

Вы можете сгладить параметры перед передачей их в ListPreparedStatementSetter, и все должно работать нормально.Я добавил пример того, как сглаживать параметры перед передачей их в подготовленный оператор выражений здесь (см. flatten метод).

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...