我们正面临一些问题,当我们尝试在Java中用BigInteger
映射BigInt
时,它的值已经改变了。我们还尝试在映射之前将其转换为longValue
,但它也失败了,因为它无法处理它的值。我们尝试使用toString()
并且它已经工作但除了使用toString()
之外还有其他任何解决方法吗?
答案 0 :(得分:2)
Java BigInteger
与SQL Server的bigint
不对应 - 尽管名称相似,但它们几乎完全不同:
BigInteger
是表示任意精度整数的类型。内部是由非稀疏字节向量表示的,随着值的增加可以自由调整大小。bigint
表示固定的64位整数。 Java等价物是long
。请注意,T-SQL的bigint
和Java的long
都是签名类型。它是由主机计算机硬件本地处理的值的固有类型。 BigInteger
可以表示任何bigint
值,但事实恰恰相反:您无法将大多数BigInteger
值存储在bigint
列中
正如您所说,您在Java中使用BigInteger
作为规范值,这意味着您无法在表格中使用bigint
,而应使用varbinary(n)
(其中{ {1}}是n
值大小的合理上限,然后像这样使用它:
BigInteger
您的实体类yourTableRow.hugeValue = yourBigIntegerValue.toByteArray()
' yourTableRow
成员的类型hugeValue
与T-SQL中的byte[]
兼容。
由于blob值的存储方式,我建议不要使用varbinary(n)
[1]。您不太可能遇到超过varbinary(MAX)
(16字节)或甚至2^128
(32字节)的整数值,因此您不需要超过2^256
或{ {1}}。
如果您知道自己的号码不会超过varbinary(16)
,那么最好将其存储为两个单独的varbinary(32)
(64位)值:
2^128
有些Java提取高8字节和低8字节:
bigint
反之亦然,以获得价值。
[1]如果值足够小,SQL Server可以选择内联存储COLUMN hugeValueUpper bigint NOT NULL,
COLUMN hugeValueLower bigint NOT NULL
值,但我会认为任何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] );
值太大而无法存储行内(因此将被移动到BLOB存储)作为错误情况的症状,因此在varbinary(MAX)
列上设置下限意味着您的程序将失败更快。
答案 1 :(得分:0)
Java BigInteger是一个任意长度的整数,仅受可用内存或实现限制的限制,而SqlServer's BIGINT
类型只是一个64位有符号整数。一旦存储在BigInteger中的值超过2 ^ 63-1,您可能会遇到截断。
如果处理超过有符号64位整数的值,则需要使用替代方法,例如使用字符串(例如VARCHAR(MAX)
)或字节数组进行存储。