如何在java

时间:2016-10-28 03:26:53

标签: java mysql primary-key uuid sql2o

我有一个表TestTable,列ID为二进制(16),名称为varchar(50)

我一直试图将有序的UUID存储为PK,如本文Store UUID in an optimized way

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

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

  

数据截断:对于列“ID”而言数据太长了在第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);

1 个答案:

答案 0 :(得分:7)

尝试将其存储为字节:

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位整数,带有一些保留位,因此该代码将其写为big-endian 128位int。 ByteBuffer只是将两个long转换为字节数组的简单方法。

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