我们面临一些问题,当我们尝试将Java中的BigInteger与sql中的BigInt映射时,其值已更改。我们还尝试在映射之前将其转换为longValue,但是由于无法处理其值而失败。我们尝试使用toString()并成功了,但是除了使用toString()之外,他们还有其他解决方法吗?

最佳答案

Java的BigInteger与SQL Server的bigint不对应-尽管名称相似,但它们几乎完全不同:


在Java中,BigInteger是代表任意精度整数的类型。在内部用非稀疏字节向量表示,该向量可随值的增加而自由调整大小。
在T-SQL中,bigint表示固定的64位整数。 Java等效为long。请注意,T-SQL的bigint和Java的long均为带符号类型。它是由主机硬件本地处理的值的固有类型。


确实,BigInteger可以表示任何bigint值,但事实并非如此:您不能在BigInteger列中存储大多数bigint值。

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

yourTableRow.hugeValue = yourBigIntegerValue.toByteArray()


您的实体类yourTableRowhugeValue成员的类型为byte[],它与T-SQL中的varbinary(n)兼容。

由于斑点值的存储方式,我建议不要使用varbinary(MAX) [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


和一些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]      );


反之亦然。

[1]的确,如果值足够小,SQL Server可以选择在一行中内联存储varbinary(MAX)值,但是我认为任何太大的BigInteger值都不能在行中存储(因此,被移到BLOB存储),因为这是错误情况的征兆,因此在varbinary(n)列上设置下限意味着您的程序将更快地失败。

关于java - Sql中的BIGINT与Java中的BigInteger之间的映射,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35883725/

10-10 18:29