java JPA短UUID?

java JPA短UUID?,java,oracle,hibernate,jpa,uuid,Java,Oracle,Hibernate,Jpa,Uuid,我的java JPA实体使用以下代码生成其UUID @Entity public class Myclass { @Id @GeneratedValue(generator = "system-uuid") @GenericGenerator(name = "system-uuid", strategy = "uuid") String id; String name; } 在Oracle和java中,ID以字符串的形式结束,如下所示: 2c96cc2

我的java JPA实体使用以下代码生成其UUID

@Entity
public class Myclass {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    String id;

    String name;
}
在Oracle和java中,ID以字符串的形式结束,如下所示:

2c96cc2a52f9f9a90152fa6549f40008

32个十六进制字符串

我必须与一些第三方系统进行交互,这些系统需要在不同的地方保存我的ID,并且必须是相同的。不幸的是,它们的字段只允许30个字符串(任何字符,而不仅仅是十六进制字符)

所以我需要我的uuid看起来像一个30个字符或更少的字符串,无论它出现在哪里(在oracle、java、第三方系统中,等等)

我应该怎么做才能使uuid的表示使用所有字母数字字符('ghi…z'但没有奇怪的字符)变得更短,以及如何确保该表示是DB和应用程序中可见的


非常感谢

如果您愿意处理一些外观奇怪的密钥,请将UUID编码为高于16的基数,例如Base36(所有字母和数字都不区分大小写)或Base64(通常不支持URL)。如果您想要URL安全且尽可能紧凑的东西,可以使用,它有特定的帮助程序用于编码和解码UUID对象

如果您愿意处理一些外观奇怪的键,请将UUID编码为高于16的基数,例如Base36(所有字母和数字都不区分大小写)或Base64(通常不支持URL)。如果您想要URL安全且尽可能紧凑的东西,可以使用,它有特定的帮助程序用于编码和解码UUID对象

谢谢你的帮助!使用base36确实可以做到这一点。但是,还需要做一件事,以确保较短的ID也是出现在DB中的ID:

 @PrePersist
 public void generateId() {
     String uuid_string = UUID.randomUUID().toString().replaceAll("-","");
     BigInteger big = new BigInteger(uuid_string, 16);
     String same_uuid_shorter_string = big.toString(36);
     id = same_uuid_shorter_string ; 
 }

(也不要使用原始的id生成器注释)

谢谢您的帮助!使用base36确实可以做到这一点。但是,还需要做一件事,以确保较短的ID也是出现在DB中的ID:

 @PrePersist
 public void generateId() {
     String uuid_string = UUID.randomUUID().toString().replaceAll("-","");
     BigInteger big = new BigInteger(uuid_string, 16);
     String same_uuid_shorter_string = big.toString(36);
     id = same_uuid_shorter_string ; 
 }

(还要去掉原始的id生成器注释)

定义“任意字符”。事实上,定义“char”。您的第三方对“字符”的定义是什么?我的意思是我可以让我的ID使用任何字母数字字符:0-9a-z,而不是像目前这样只使用十六进制字符。UUID并不总是保证唯一的。@Tiny我认为OP并不真正关心这一点(在现实生活中,两个完全相同的UUID非常罕见);OP更感兴趣的是如何在他的UUID和第三方需求之间获得双射。至少这是我所理解的。@Tiny->定义“any char”。事实上,定义“char”。第三方对“char”的定义是什么?我的意思是,我可以让我的ID使用任何字母数字字符:0-9a-z,而不是像现在这样只使用十六进制字符。UUID并不总是保证唯一的。@Tiny我认为OP并不真正关心这一点(在现实生活中,两个相同的UUID是非常罕见的);OP对在UUID和第三方需求之间获得双射的方法更感兴趣。至少这是我所理解的。@Tiny->有趣,但是(太懒了以至于无法计算)这能将任何UUID减少到小于(或等于)的一系列吗30个字符,因为OP似乎需要?@fge UUID是128位长的,所以任何比基20更有效的方法都应该有效(我不记得我手机上的公式)。IIRC Base58不会超过21个字符。所以我在entity类中添加了一个getId()和setId()方法,可以从base16字符串转换为base36字符串,然后再转换回来(使用BigDecimal)。例如2c96cc2a52fab0ae0152fab0d60d0000 2n15kgjgtgcoa04nb6a1yxi4g。在我的java应用程序中,这很好,但不幸的是在Oracle中,DB包含长的十六进制版本:-(好的,找到了一种可行的方法并将在下面发布。感谢您的帮助!很有趣,但是(太懒了,无法进行计算)这真的能像OP所要求的那样,将任何UUID减少到少于(或等于)30个字符的序列吗?@fge一个UUID是128位长的,所以任何比基20更有效的方法都应该有效(我记不起我手机上的公式)。IIRC Base58不会超过21个字符。所以我在我的实体类中添加了一个getId()和setId()方法将base16字符串转换为base36字符串并返回(使用BigDecimal)。例如2c96cc2a52fab0ae0152fab0d60d0000 2n15kgjgtgcoa04nb6a1yxi4g。在我的java应用程序中,这很好,但不幸的是在Oracle中,DB包含长的十六进制版本:-(好的,找到了一种可行的方法,并将在下面发布。感谢帮助!