我们面临一些问题,当我们尝试将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()
您的实体类
yourTableRow
的hugeValue
成员的类型为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/