2016-02-19 61 views
0

我的Java JPA實體使用下面的代碼來生成它的UUIDjava 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',但沒有奇怪的字符)變得更短,以及如何確保這種表示法在數據庫中可見並在應用程序?

非常感謝

+1

定義「任何字符」。實際上,定義「char」。你的第三方定義爲「字符」是什麼? – fge

+0

我的意思是我可以讓我的ID使用任何字母數字字符:0-9a-z,而不是僅使用十六進制字符,因爲它是目前的情況。 – MikaelW

+0

UUID並不總是保證是唯一的。 – Tiny

回答

2

如果你願意處理一些古怪的鑰匙,在基本高於16,如Base36編碼的UUID(所有的字母和數字,可以不區分大小寫)或Base64(通常不是URL安全的)。如果您想要儘可能緊湊的網址安全,您可以使用my implementation of Flickr-compatible Base58,它具有特定的助手來編碼和解碼UUID對象。

+0

有趣的,但(懶得做計算)可以實際上減少任何UUID到一系列小於(或等於)30個字符,因爲OP似乎需要? – fge

+0

@fge一個UUID是128位長,所以比基本20更有效率的任何東西都可以工作(我記不起我手機上的公式)。 IIRC Base58不會超過21個字符。 – chrylis

+0

所以我在我的實體類中添加了一個getId()和setId()方法,它將base16字符串轉換爲base36字符串,並返回(使用BigDecimal)。例如2c96cc2a52fab0ae0152fab0d60d0000 <> 2n15kgjgtgcoa04nb6a1yxi4g。在我的java應用程序中,它很好,但不幸的是,在Oracle中,數據庫包含長的十六進制版本:-( – MikaelW

0

感謝您的幫助!使用base36確實有訣竅。還有一兩件事是必要的但要確保更短的ID是出現在DB以及一個:

@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生成的註釋)