Sql 中的 BIGINT 与 Java 中的 BigInteger 之间的映射

Ash*_*wal 2 java sql-server biginteger

我们面临一些问题,当我们尝试BigInteger在 Java 中使用BigIntsql进行映射时,它的值发生了变化。我们也尝试将其转换为longValue映射之前,但它也失败了,因为它无法处理它的值。我们尝试过toString(),它奏效了,但除了使用之外,他们还有其他解决方法toString()吗?

Dai*_*Dai 5

JavaBigInteger与 SQL Server 不对应bigint——尽管名称相似,但它们几乎完全不同:

  • 在 Java 中,BigInteger是表示任意精度整数的类型。在内部是由一个非稀疏字节向量表示,它可以随着值的增加而自由调整大小。
  • 在 T-SQL 中,bigint表示固定的 64 位整数。Java 等价物是long. 请注意,T-SQLbigint和 Javalong都是有符号类型。它是由主机硬件本地处理的值的固有类型。

确实BigInteger可以表示任何bigint值,但反之则不然:您不能将大多数BigInteger值存储在bigint列中。

正如你说你BigInteger在 Java 中使用作为你的规范值,这意味着你不能bigint在你的表中使用,你应该使用varbinary(n)(哪里n是你的BigInteger值大小的一些合理的上限,然后像这样使用它:

yourTableRow.hugeValue = yourBigIntegerValue.toByteArray()
Run Code Online (Sandbox Code Playgroud)

您的实体类yourTableRowhugeValue成员属于byte[]varbinary(n)T-SQL兼容的类型。

varbinary(MAX)由于 blob 值的存储方式,我建议不要使用[1]。您不太可能遇到超过2^128(16 个字节)甚至2^256(32 个字节)的整数值,因此您不需要超过varbinary(16)varbinary(32)

如果您知道您的数字不会超过2^128您最好将其存储为两个单独的bigint(64 位)值:

COLUMN hugeValueUpper bigint NOT NULL,
COLUMN hugeValueLower bigint NOT NULL
Run Code Online (Sandbox Code Playgroud)

还有一些Java提取高8个字节和低8个字节:

byte[] bytes = someBigIntegerValue.toByteArray();
if( bytes.length > 16 ) throw ...

yourRow.hugeValueLower = (long)bytes[ 0] << 56) | 
                         (long)bytes[ 1] << 48) |
                         (long)bytes[ 2] << 40) |
                         (long)bytes[ 3] << 32) |
                         (long)bytes[ 4] << 24) |
                         (long)bytes[ 5] << 16) |
                         (long)bytes[ 6] <<  8) |
                         (long)bytes[ 7]      );
yourRow.hugeValueUpper = (long)bytes[ 8] << 56) |
                         (long)bytes[ 9] << 48) |
                         (long)bytes[10] << 40) |
                         (long)bytes[11] << 32) |
                         (long)bytes[12] << 24) |
                         (long)bytes[13] << 16) |
                         (long)bytes[14] <<  8) |
                         (long)bytes[15]      );
Run Code Online (Sandbox Code Playgroud)

反之亦然以获取值。

[1]varbinary(MAX)如果值足够小,SQL Server 确实会选择将值存储在一行中,但我会考虑任何BigInteger太大而无法存储在行中的值(因此会被移动到 BLOB 存储)作为错误情况的征兆,因此在varbinary(n)列上设置下限意味着您的程序将失败得更快。