Использование Integer Array в postgres с Spring-boot - PullRequest
0 голосов
/ 18 октября 2018

Я пытаюсь принять из браузера список и использовать его в запросе SQL к базе данных postgres.У меня есть следующий фрагмент кода, который пытается показать функцию, которую я сделал для этого.Некоторые переменные были изменены в случае появления расхождений.

static public List<Map<String,Object>> fetch(NamedParameterJdbcTemplate jdbcTemplate, List<Integer> id){
    List<Map<String,Object>> result= new ArrayList<>();
    String sql = "select * from lookup where id && ARRAY[ :ids ]";
    MapSqlParameterSource parameters = new MapSqlParameterSource();
    parameters.addValue("ids",id, Types.INTEGER);
    result= jdbcTemplate.query(sql,
            parameters,
            new RowMapper<Map<String,Object>>() { ...
            }
    )
}

Поле id таблицы поиска является массивом postgress, поэтому мне нужно использовать && и функцию массива

Эта функция вызывается многими различными конечными точками и передает NamedParameterJdbcTemplate, а такжесписок целых чисел.Проблема, с которой я сталкиваюсь, заключается в том, что если в списке есть целое число <100, я получаю следующее сообщение </p>

Bad value for type int : {20}

Есть ли другой способ сделать это или обойти эту ошибку?

РЕДАКТИРОВАТЬ:

Кажется, что это было частью проблемы, упомянутой в качестве ответа, но также с использованием

rs.getInt(col) 

вместо

rs.getArray(col)

1 Ответ

0 голосов
/ 18 октября 2018

Я вижу ошибку в SQL и, возможно, неправильный выбор API после этого.Сначала в запросе:

select * from lookup where id && ARRAY[ :ids ]

Чтобы связать параметр массива, его не следует помещать в конструктор ARRAY, а вместо этого необходимо использовать привязку JDBC, например:

select * from lookup where id && ?

Как вы заметили, я не использую именованный параметр в этих примерах, потому что NamedParameterJdbcTemplate не предоставляет маршрут для получения объекта java.sql.Connection или его прокси.Вы можете получить к нему доступ через PreparedStatementSetter, если вместо этого используете интерфейс JdbcOperations.

public static List<Map<String,Object>> fetch(NamedParameterJdbcTemplate jdbcTemplate, List<Integer> idlist){
    List<Map<String,Object>> result= new ArrayList<>();
    String sql = "select * from lookup where id && ?";
    final Integer[] ids = idlist.toArray(new Integer[0]);
    PreparedStatementSetter parameters = new PreparedStatementSetter() {
        @Override
        void setValues(PreparedStatement stmt) {
            Connection conn = stmt.getConnection();
            // this can only be done through the Connection
            java.sql.Array arr = conn.createArrayOf("integer", ids);
            // you can use setObject(1, ids, java.sql.Types.ARRAY) instead of setArray
            // in case the connection wrapper doesn't pass it on to the JDBC driver
            stmt.setArray(1, ids);
        }
    };
    JdbcOperations jdo = jdbcTemplate.getJdbcOperations();
    result= jdo.query(sql,
            parameters,
            new RowMapper<Map<String,Object>>() { ...
            }
    )
}

В коде могут быть ошибки, поскольку я обычно использую другой набор API, и вам нуженБлок try-catch для java.sql.SQLException в этой функции setValues, но с этого момента вы сможете справиться с этим.

...