在带有 Spring-boot 的 postgres 中使用整数数组

Posted

技术标签:

【中文标题】在带有 Spring-boot 的 postgres 中使用整数数组【英文标题】:Using Integer Array in postgres with Spring-boot 【发布时间】:2019-03-23 09:29:55 【问题描述】:

我正在尝试从浏览器接受一个 List 并在 SQL 查询中使用它来访问 postgres 数据库。我有以下代码 sn-p 试图显示我所做的功能。一些变量已经改变,以防出现差异。

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 以及一个整数列表。我遇到的问题是,如果列表中的任何整数

Bad value for type int : 20

有没有其他方法可以解决这个错误?

编辑:

它似乎是作为答案提到的问题的一部分,但也在使用

rs.getInt(col) 

而不是

rs.getArray(col)

【问题讨论】:

【参考方案1】:

我可以在 SQL 中看到一个错误,之后可能是错误的 API 选择。首先在查询中:

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

要绑定一个数组参数,它不能放在ARRAY构造函数中,而是你需要像这样使用JDBC绑定:

select * from lookup where id && ?

正如您所注意到的,我在这些示例中没有使用命名参数,因为NamedParameterJdbcTemplate 没有提供获取java.sql.Connection 对象或它的代理的路径。如果您使用JdbcOperations 接口,则可以通过PreparedStatementSetter 访问它。

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 函数中为 java.sql.SQLException 设置一个 try-catch 块,但您应该能够从这里处理它开。

【讨论】:

我使用的方法是 spring 展示了如何使用数组并将参数替换为正确数量的 ?是我的理解。虽然这种方式看起来更像我想要的所以我会试试这个 实际上只是尝试使用此代码,我得到与以前相同的错误 那么你的 id 字段不是你所说的数组,而是整数甚至 bigint。将 where 子句更改为 id = any( ? ) 它肯定是一个数组,这是我得到的任何运算符不存在的错误:integer[] = integer 嗯...根据***.com/q/50818649/3841161,那么问题不在于添加值时,而在于提取它们时。错误在您的 RowMapper 中。当您应该使用 getArray(col) 时,您可能会在 id 列上调用 rs.getInt(col)。但是您的原始代码仍然可能无法用于数组中的多个值。

以上是关于在带有 Spring-boot 的 postgres 中使用整数数组的主要内容,如果未能解决你的问题,请参考以下文章

为啥 spring-boot 和 postgres 连接会在一段时间后断开?

无法将 AWS-Postgres 服务器与带有 heroku 托管的 Spring Boot 应用程序连接起来

Spring-boot JPA 连接到 postgres,其中在运行时提供数据库和模式

spring-boot:数据库中断后jdbc重新连接

docker-compose:spring-boot web 服务访问 postgres db 服务

连接被拒绝 postgres docker