按StackOverflow方案将UUID转为Binary(16)存入SQL仍报错,求解答
问题分析与解决方案
首先,我们拆解你遇到的两个核心问题:
1. 为什么修改ByteBuffer大小为8会抛出BufferOverflowException?
UUID本质是**128位(16字节)**的唯一标识符,它被拆分为两个64位(8字节)的长整型:mostSignificantBits和leastSignificantBits。你的代码需要把这两个8字节的long依次写入ByteBuffer,所以ByteBuffer的容量必须至少是16字节。
当你把ByteBuffer的大小改成8时,写入第一个long(8字节)就已经把缓冲区填满了,再尝试写入第二个long自然会触发BufferOverflowException——这完全符合预期,因为8字节的空间根本装不下16字节的数据。
2. 为什么按照方案用BINARY(16)会报错,改成BINARY(32)就正常?
这里的核心误解是MySQL中BINARY(n)的n代表字节数,不是十六进制字符数:
BINARY(16)表示存储16字节的二进制数据,刚好匹配UUID的二进制长度;BINARY(32)则是存储32字节的二进制数据,远大于实际需要。
你用BINARY(16)报错的原因大概率是参数传递时的类型不匹配:你的InsertQueryBuilder可能没有把字节数组当作二进制参数传递给JDBC,而是自动转换成了字符串。比如,16字节的二进制数组如果被转成UTF-8字符串,长度会远超过16字节,导致Data too long for column 'id';而BINARY(32)的容量足够容纳这个转码后的字符串,所以不会报错。
修复步骤:
- 确保数据库表的
id列类型是BINARY(16)(不要用32,会浪费存储空间); - 检查你的
InsertQueryBuilder实现,确保它将字节数组参数以二进制类型传递给JDBC(比如使用PreparedStatement.setBytes()方法,而不是setString()); - 保持ByteBuffer的容量为16字节,这是存储UUID二进制数据的正确大小。
内容的提问来源于stack exchange,提问作者Anum Sheraz
相关产品推荐
相关产品推荐

