【问题标题】:How to pass BigInteger from java to Postgres?如何将 BigInteger 从 java 传递到 Postgres?
【发布时间】:2013-05-03 11:16:06
【问题描述】:

我需要将 BigInteger 参数传递给 SQL 查询。 (在 Postgres 9.2 上) 我的 DAO 中有这段代码:

    public List<PersonInfo> select(String id) {
        BigInteger bigIntId = new BigInteger(id);
        JdbcTemplate select = new JdbcTemplate(dataSource);
        return select
            .query("SELECT * FROM PE.SUPPLIER_INPUT_DATA WHERE ID = ?",
                    new Object[] { bigIntId },
                    new PersonRowMapper());
    }

我收到以下异常:

{"error":"Error invoking getPersonInfoById.[org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; 
bad SQL grammar [SELECT * FROM PE.SUPPLIER_INPUT_DATA WHERE ID = ?]; 
nested exception is org.postgresql.util.PSQLException: 
Can't infer the SQL type to use for an instance of java.math.BigInteger. 
Use setObject() with an explicit Types value to specify the type to use.]"}

id 是 bigint 类型

试图传递纯字符串 - 也会引发类型异常。 谷歌搜索异常中的消息 - 没有相关结果。 有任何想法吗?

【问题讨论】:

  • ID 属于哪种数据类型?
  • JDBC 规范不包括对BigInteger 的支持;您要么需要使用不同的数据类型(例如比例为 0 的 BigDecimal),要么查看 PostgreSQL 驱动程序是否提供了一些特定于实现的方法来设置 BigInteger 值。
  • 尝试将其作为Number 传递,也许可行?
  • 尝试改用 java.lang.Long。
  • @Mark Rotteveel,介意发表您的评论作为答案,这样我可以接受吗?

标签: java spring postgresql jdbc postgresql-9.2


【解决方案1】:

在 JDBC 4.1 (Java 7) 中添加了对 BigInteger 的支持,不知何故,当我最初写这个答案时,我错过了。

特别是第 3.1 节 JDBC 4.1 规范变更概述:

  • 表 B-4 的其他映射,从 Java 对象到 JDBC 类型的映射
    [..]
    还添加了支持以将 java.lang.BigInteger[sic] 映射到 JDBC BIGINT
  • 到表 B-5 的其他映射,由 setObjectsetNull 在 Java 对象类型和目标 JDBC 类型之间执行
    [..]
    允许将 java.lang.BigInteger[sic] 转换为 CHARVARCHARLONGVARCHARBIGINT

我不确定驱动程序对此的支持程度。

原答案

JDBC 规范不包括对BigInteger 的支持;您要么需要使用不同的数据类型(例如 BigDecimal 比例为 0),要么找出 PostgreSQL 驱动程序是否提供了一些特定于实现的方法来设置 BigInteger 值。

【讨论】:

  • @valijon 建议您编辑不合适。你是正确的,这个类被称为java.math.BigInteger,但这是来自 JDBC 4.1 规范的文字引用,它有这个错误。
【解决方案2】:

我遇到了同样的问题,使用 Types.BIGINT 作为改进作品。我将它与 BatchPreparedStatementSetter 结合使用,这样简单易读:

 @Transactional
public void saveStuff(List<Foo> foos) {
    int batchSize = foos.size();

    String sql = "INSERT INTO db.foo " +
            "(sting_id, a_big_integer, bar, ..etc ) " +
            "VALUES (?, ?, ?, ..etc )";

        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                FeedEntry feedEntry = feedEntries.get(i);
                int index = 1;
                ps.setString(index++, foo.id());
                ps.setObject(index++, foo.getTheBigInteger(), Types.BIGINT);
                ps.setString(index++, foo.bar())
                //etc
            }

            @Override
            public int getBatchSize() {
                return foos.size();
            }
        });

}

【讨论】:

    【解决方案3】:

    您可以使用java.math.BigDecimal 转换BigInt。 下面的代码应该可以工作:

    public List<PersonInfo> select(String id) {
    
        BigDecimal bigDecId = new BigDecimal(id);
        JdbcTemplate select = new JdbcTemplate(dataSource);
        return select
            .query("SELECT * FROM PE.SUPPLIER_INPUT_DATA WHERE ID = ?",
                    new Object[] { bigDecId },
                    new PersonRowMapper());
    }
    

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题,我将驱动程序从 9.3 更新到了 42.2.2。然后工作正常

          <dependency>
              <groupId>org.postgresql</groupId>
              <artifactId>postgresql</artifactId>
              <version>${postgresql.version}</version>
          </dependency>
      

      【讨论】:

        猜你喜欢
        • 2023-01-13
        • 1970-01-01
        • 2017-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-08
        • 2010-10-23
        相关资源
        最近更新 更多