【问题标题】:java JPA shorter UUID?java JPA更短的UUID?
【发布时间】:2016-02-19 17:23:33
【问题描述】:

我的 java JPA Entity 使用下面的代码来生成它的 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' 但没有奇怪的字符)更短,以及如何确保该表示在数据库中可见并且在应用中?

非常感谢

【问题讨论】:

  • 定义“任何字符”。事实上,定义“char”。您的第三方将什么定义为“字符”?
  • 我的意思是我可以让我的 ID 使用任何字母数字字符:0-9a-z,而不是像现在这样只使用十六进制字符。
  • UUID 并不总是保证是唯一的。
  • @Tiny 我认为 OP 并不真正关心这一点(在现实生活中,两个相同的 UUID 无论如何都非常罕见); OP 对在他的 UUID 和第三方需求之间获得双射的方法更感兴趣。至少我是这么理解的。

标签: java oracle hibernate jpa uuid


【解决方案1】:

如果您愿意处理一些看起来很奇怪的键,请将 UUID 编码为高于 16 的基数,例如 Base36(所有字母和数字,可以不区分大小写)或 Base64(通常不是 URL-安全的)。如果您想要尽可能紧凑的 URL 安全的东西,您可以使用 my implementation of Flickr-compatible Base58,它具有用于编码和解码 UUID 对象的特定帮助程序。

【讨论】:

  • 有趣,但是(懒得计算)实际上可以将任何 UUID 减少到一系列小于(或等于)30 个字符,正如 OP 似乎要求的那样?
  • @fge UUID 的长度为 128 位,因此任何比大约 20 位更有效的方法都应该有效(我不记得手机上的公式了)。 IIRC Base58 不会超过 21 个字符。
  • 所以我在我的实体类中添加了一个 getId() 和 setId() 方法,它们从 base16 字符串转换为 base36 字符串并返回(使用 BigDecimal)。例如 2c96cc2a52fab0ae0152fab0d60d0000 2n15kgjgtgcoa04nb6a1yxi4g。在我的 java 应用程序中,它很好,但不幸的是,在 Oracle 中,数据库包含长的十六进制版本:-(
  • 好的,找到了一种可行的方法并将其发布在下面。感谢您的帮助!
【解决方案2】:

感谢您的帮助!使用 base36 确实可以解决问题。然而,还需要做一件事来确保较短的 ID 也是出现在数据库中的 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生成器注解)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-14
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多