java - 如何在 java 中将 UUID 保存为二进制 (16)

标签 java mysql primary-key uuid sql2o

我有一个表 TestTable,其列 ID 为 binary(16),名称为 varchar(50)

我一直在尝试将有序的 UUID 存储为 PK,就像本文中的一样 Store UUID in an optimized way

我看到 UUID 在数据库中保存为 HEX (blob)

所以我想从 java 中保存这个 ID 但我收到了这个错误

Data truncation: Data too long for column 'ID' at row 1

我目前正在使用库 sql2o 与 mysql 交互

基本上这是我的代码

String suuid = UUID.randomUUID().toString();
String partial_id = suuid.substring(14,18) + suuid.substring(9, 13) + suuid.substring(0, 8) + suuid.substring(19, 23) + suuid.substring(24)
String final_id = String.format("%040x", new BigInteger(1, partial_id.getBytes()));
con.createQuery("INSERT INTO TestTable(ID, Name) VALUES(:id, :name)")
        .addParameter("id", final_id)
        .addParameter("name", "test1").executeUpdate();

部分 ID 应该是这样的 11d8eebc58e0a7d796690800200c9a66

我在 mysql 中试过这条语句没有问题

insert into testtable(id, name) values(UNHEX(CONCAT(SUBSTR(uuid(), 15, 4),SUBSTR(uuid(), 10, 4),SUBSTR(uuid(), 1, 8),SUBSTR(uuid(), 20, 4),SUBSTR(uuid(), 25))), 'Test2');

但是当我删除 unhex 函数时,我得到了同样的错误。那么如何将正确的 ID 从 Java 发送到 mysql?

更新

我根据 David Ehrmann 的答案解决了我的问题.但就我而言,我使用 tomcat 中的 HexUtils 将排序后的 UUID 字符串转换为 bytes[]:

byte[] final_id = HexUtils.fromHexString(partial_id);

最佳答案

尝试将其存储为字节:

UUID uuid = UUID.randomUUID();
byte[] uuidBytes = new byte[16];
ByteBuffer.wrap(uuidBytes)
        .order(ByteOrder.BIG_ENDIAN)
        .putLong(uuid.getMostSignificantBits())
        .putLong(uuid.getLeastSignificantBits());

con.createQuery("INSERT INTO TestTable(ID, Name) VALUES(:id, :name)")
    .addParameter("id", uuidBytes)
    .addParameter("name", "test1").executeUpdate();

一点解释:您的表使用的是 BINARY(16),因此将 UUID 序列化为其原始字节是一种非常简单的方法。 UUID 本质上是具有一些保留位的 128 位整数,因此此代码将其写为大端 128 位整数。 ByteBuffer 只是将两个 long 转换为字节数组的简单方法。

现在在实践中,所有的转换工作和头痛都不值得你每行节省 20 个字节。

关于java - 如何在 java 中将 UUID 保存为二进制 (16),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40297600/

相关文章:

php - Mysql 在插入时抛出错误

mysql - 我是否能够在没有自动递增数字列的情况下执行基于数字的操作?

mysql - FOREIGN KEY ... REFERENCE 没有错误,但只是数据库中的空列

java - LocalDate 上个月的最后一个工作日

java - 从字符串中读取 rdf 模型

java - 在 JVM 内部和跨 JVM 同步共享文件写入

mysql - 从字符串转换日期和/或时间时转换失败。 - 错误

Mysql FROM_UNIXTIME 为 UTC

sql-server-2008-r2 - 子表的主键是否正确?

java - cassandra 1.1.2 中的数据丢失