Нет результата «In» в PreparedStatement с 2 объектами - PullRequest
0 голосов
/ 04 июля 2019

Я потратил много времени, чтобы найти решение, но все еще не могу.

Я нашел какое-то решение о том, как передать элементы "IN" в PreparedStatement, но если есть какое-то другое решение, я был бы рад увидеть это, но, в любом случае, у меня есть

RowMapper<Map<BigInteger, Status>> mapper = new QueryDescriptionById.RowMapperDescription();

@Override
public Multimap<BigInteger, Status> findObject(BigInteger[] ids) {
    StringBuilder builder = new StringBuilder();
    for (Object id : ids) {
        builder.append("?,");
    }
    String statement = SQL + builder.deleteCharAt(builder.length() - 1).toString() + ")";

    Multimap<BigInteger, Status> multimap = ArrayListMultimap.create();
    intoMap(multimap, getJdbcTemplate().query(statement, ps -> {
        int index = 1;
        for (BigInteger id : ids) {
            ps.setInt(index++, id.intValue());
        }
    }, mapper));
    return multimap;
 }

private void intoMap(Multimap<BigInteger, Status> multimap, List<Map<BigInteger, Status>> list) {
    list.forEach(map -> map.forEach((multimap::put)));
}

class RowMapperDescription implements RowMapper {
        @Override
        public Map<BigInteger, Status> mapRow(ResultSet rs, int rowNum) throws SQLException {
            Status status = new Status();
            Map<BigInteger, Status> map = new HashMap<>();
            BigInteger id = rs.getBigDecimal("ID").toBigInteger();
            BigInteger parentId = rs.getBigDecimal("PARENT_ID").toBigInteger();
            status.setId(id);
            status.setDescription(rs.getString("attempt_status_text"));
            map.put(parentId, status);
            return map;
        }
    }

Но это работает хорошо, когда я передаю в BigInteger [] только 1 элемент, но когда их 2 или более, он не попадает в мой маппер.

Почему?

P.S

Вместо RowMapper я пытался использовать ResultSet, как

return getJdbcTemplate().query(SQL, ids, resultSet -> {
            Multimap<BigInteger, Status> multimap = ArrayListMultimap.create();
            int rowNum = 0;
            while (resultSet.next()) {
                System.out.println("rownum = " + rowNum);
                mapper.mapRow(resultSet, rowNum++).forEach(multimap::put);
            }
            return multimap;
        })

Но в консоли не было никаких строк, которые означают, что resultSet не имеет next()

P.S.S

Мой SQL - это где сложно, поэтому я поставил только короткую версию. Похоже

private String SQL = "select el1,el2 from mytable where el3 in(";

Я пробовал вместо in("; и in :ID и in = :ID и in (:ID) и in (?) и некоторые другие варианты, которые я не помню (-:

EDITED

На самом деле, я не понимаю, почему это работает

public QueryDescriptionBySmsId(DataSource dataSource) {
    super(dataSource, SQL);
    logger.debug("Created QueryStatus");
    declareParameter(new SqlParameter("ID", Types.NUMERIC));
    compile();
    logger.debug("Created QueryStatus");
}

@Override
public Multimap<BigInteger, Status> query(Set<BigInteger> ids) {
       Map<String, Set> paramMap = Collections.singletonMap("ID", smsIds);
       List l = executeByNamedParam(paramMap); // it returns a lot of elements which I am looking for
}

Но это не работает

 @Override
 public Multimap<BigInteger, SmsStatus> query(Set<BigInteger> sids) {

        Map<String, Set> paramMap = Collections.singletonMap("ID", ids);
        return getJdbcTemplate().query(SQL,  resultSet -> {
            int rowNum = 0;
            Multimap<BigInteger, SmsStatus> multimap = 
 ArrayListMultimap.create();
            while (resultSet.next()) {
                mapper.mapRow(resultSet, rowNum++).forEach(multimap::put);
            }
            return multimap;
        },paramMap);
 }

Показывает ошибку

Состояние SQL [99999]; код ошибки [17004]; Неверный тип столбца

1 Ответ

0 голосов
/ 05 июля 2019

Я так изменил свой код, и теперь он работает, но мне не нравится это решение

public class QueryDescriptionById extends SqlQuery implements IQueryDescriptionById {

RowMapper<Map<BigInteger, Status>> mapper = new RowMapperDescription();

public QueryDescriptionById(DataSource dataSource) {
    super(dataSource, SQL);
}

public Multimap<BigInteger, SmsStatus> query(Set<BigInteger> ids) {

    Map<String, Set> paramMap = Collections.singletonMap("ID", ids);
    NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(getJdbcTemplate().getDataSource());

    return template.query(SQL, paramMap, resultSet -> {
        int rowNum = 0;
        Multimap<BigInteger, Status> multimap = ArrayListMultimap.create();
        while (resultSet.next()) {
            mapper.mapRow(resultSet, rowNum++).forEach(multimap::put);
        }
        return multimap;
    });
}
.........
.........
.........
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...