使用Java中的BigInteger在Sql中的BIGINT之间进行映射

时间:2016-03-09 05:36:10

标签: java sql-server biginteger

我们正面临一些问题,当我们尝试在Java中用BigInteger映射BigInt时,它的值已经改变了。我们还尝试在映射之前将其转换为longValue,但它也失败了,因为它无法处理它的值。我们尝试使用toString()并且它已经工作但除了使用toString()之外还有其他任何解决方法吗?

2 个答案:

答案 0 :(得分:2)

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)(其中{ {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))或字节数组进行存储。