首页 > 解决方案 > 在带有 Spring-boot 的 postgres 中使用整数数组

问题描述

我试图从浏览器中接受一个 List 并在 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,我会收到以下消息

Bad value for type int : {20}

有没有另一种方法可以做到这一点或解决这个错误?

编辑:

看来这是作为答案提到的问题的一部分,但也使用

rs.getInt(col) 

代替

rs.getArray(col)

标签: postgresqlspring-bootjdbctemplate

解决方案


我可以在 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,并且您需要java.sql.SQLException在该setValues函数中使用 try-catch 块,但您应该能够从这里开始处理它。


推荐阅读