如何将Java中的BigInteger传递到PostgreSQL?

6

我需要将一个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是哪种数据类型? - AllTooSir
3
JDBC规范不支持BigInteger,你需要使用其他数据类型(例如具有0精度比例的BigDecimal),或查找PostgreSQL驱动程序是否提供一些特定于实现的方法来设置BigInteger值。 - Mark Rotteveel
尝试将其作为 Number 传递,也许会起作用? - Kai
尝试使用 java.lang.Long。 - Nitram76
@Mark Rotteveel,能否将您的评论发布为答案,这样我就可以接受它了吗? - aviad
4个回答

5
在JDBC 4.1(Java 7)中添加了对BigInteger的支持,当我原先写这篇答案时,不知道这一点。具体而言,JDBC 4.1规范的第3.1节概述更改内容如下:
  • 在表B-4的映射中添加了其他映射,从Java对象到JDBC类型
    [..]
    还增加了将java.lang.BigInteger[sic]映射到JDBC BIGINT的支持。
  • 在表B-5的由setObjectsetNull执行的映射中添加了其他映射,介于Java对象类型和目标JDBC类型之间
    [..]
    允许将java.lang.BigInteger[sic]转换为CHARVARCHARLONGVARCHARBIGINT
我不确定各种驱动程序对此支持的情况如何。

原始答案

JDBC规范不支持BigInteger;您需要使用不同的数据类型(例如精度为0的BigDecimal),或查找PostgreSQL驱动程序是否提供某些实现特定的方法来设置BigInteger值。

@valijon,您的建议编辑不太合适。您是正确的,该类被称为java.math.BigInteger,但这是来自JDBC 4.1规范的字面引用,其中存在此错误。 - Mark Rotteveel

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();
            }
        });

}

0

我曾经遇到过同样的问题,我将驱动程序从9.3更新到了42.2.2版本,然后问题得到了解决。

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

0
您可以使用 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());
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接