How to save a UUID as binary(16) in java

无人久伴 提交于 2019-12-05 02:29:31

问题


I have a table TestTable with columns ID as binary(16) and name as varchar(50)

I've been trying to store an ordered UUID as PK like in this article Store UUID in an optimized way

I see the UUID is saved in database as HEX (blob)

So I want to save this ID from java but I am getting this error

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

I am currently using the library sql2o to interact with mysql

So basically this is my code

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();

The partial id should be something like this 11d8eebc58e0a7d796690800200c9a66

I tried this statement in mysql without issue

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');

But I got the same error when I remove the unhex function. So how can I send the correct ID from Java to mysql?

UPDATE

I solved my problem inspired on the answer of David Ehrmann. But in my case I used the HexUtils from tomcat to transform my sorted UUID string into bytes[]:

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

回答1:


Try storing it as bytes:

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();

A bit of an explanation: your table is using BINARY(16), so serializing UUID as its raw bytes is a really straightforward approach. UUIDs are essentially 128-bit ints with a few reserved bits, so this code writes it out as a big-endian 128-bit int. The ByteBuffer is just an easy way to turn two longs into a byte array.

Now in practice, all the conversion effort and headaches won't be worth the 20 bytes you save per row.



来源:https://stackoverflow.com/questions/40297600/how-to-save-a-uuid-as-binary16-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!