Base64壓縮UUID長度替換Hibernate原有UUID產生器

來源:互聯網
上載者:User

標籤:

本文來自http://my.oschina.net/noahxiao/blog/132277,個人儲藏使用

1、背景

在採用Hibernate做對象映射時,我一直都採用UUID來做主鍵。由於Hibernate的UUID需要佔用32位的字元,所以一般都會讓人感覺響效率且增加儲存佔用。

我在查看公司項目時發現了一種比較好的產生UUID的方法,就是將UUID資料進行Base64化。覺得比較有意義拿出來給大家分享。

2、傳統UUIDa、java.util.UUID

Java中的UUID採用RFC 4122的標準,按標準資料按16進位進行表示(36個字元)。如:f81d4fae-7dec-11d0-a765-00a0c91e6bf6

b、Hibernate UUID

Hibernate預設產生的UUID與RFC 4122標準相比,去掉了沒有用的"-"分割符號,所以更短(32個字元)。如:f81d4fae7dec11d0a76500a0c91e6bf6

3、Base64格式的UUID

由於Base64編碼使用的字元包括大小寫字母各26個,加上10個數字,和加號“+”,斜杠“/”,一共64個字元。所以才有Base64名字的由來。Base64相當於使用64進位來表示資料,相同長度位元的情況下要比16進位表示更多的內容。

由於UUID標準資料總共是128-bit,所以我們就可以對這個128-bit重新進行Base64編碼。

128-bit的UUID在Java中表示為兩個long型資料,可以採用java.util.UUID中的getLeastSignificantBits與getMostSignificantBits分別獲得兩個long(64-bit)。再通過Base64轉碼就可以獲得我們所要的UUID。

UuidUtils工具類

package org.noahx.uuid; import org.apache.commons.codec.binary.Base64; import java.util.UUID; public abstract class UuidUtils {     public static String uuid() {        UUID uuid = UUID.randomUUID();        return uuid.toString();    }     public static String compressedUuid() {        UUID uuid = UUID.randomUUID();        return compressedUUID(uuid);    }     protected static String compressedUUID(UUID uuid) {        byte[] byUuid = new byte[16];        long least = uuid.getLeastSignificantBits();        long most = uuid.getMostSignificantBits();        long2bytes(most, byUuid, 0);        long2bytes(least, byUuid, 8);        String compressUUID = Base64.encodeBase64URLSafeString(byUuid);        return compressUUID;    }     protected static void long2bytes(long value, byte[] bytes, int offset) {        for (int i = 7; i > -1; i--) {            bytes[offset++] = (byte) ((value >> 8 * i) & 0xFF);        }    }     public static String compress(String uuidString) {        UUID uuid = UUID.fromString(uuidString);        return compressedUUID(uuid);    }     public static String uncompress(String compressedUuid) {        if (compressedUuid.length() != 22) {            throw new IllegalArgumentException("Invalid uuid!");        }        byte[] byUuid = Base64.decodeBase64(compressedUuid + "==");        long most = bytes2long(byUuid, 0);        long least = bytes2long(byUuid, 8);        UUID uuid = new UUID(most, least);        return uuid.toString();    }     protected static long bytes2long(byte[] bytes, int offset) {        long value = 0;        for (int i = 7; i > -1; i--) {            value |= (((long) bytes[offset++]) & 0xFF) << 8 * i;        }        return value;    }}

通過調用UuidUtils.compressedUuid()方法就可以獲得我的需要的UUID字串(22個字元,128-bit的Base64隻需要22個字元)。如:BwcyZLfGTACTz9_JUxSnyA

比Hibernate32個字元還短了10個字元。

在處理Base64時,這裡用到了apache的commons-codec編碼工具包,因為它提供了簡單的編碼轉換方法。而且還有encodeBase64URLSafeString方法,採用URL安全方式產生Base64編碼。預設的Base64含有+與/字元,如果這種編碼出現在URL中將造成混亂。URL安全方式採用了-替換+,_替換/,並去掉了結束==。非常適合Web直接傳參。

4、Hibernate的UUID產生器

由於Hibernate4對SessionImplementor的包做出了調整所以ID產生器的實現稍有不同(import)。

a、Hibernate3
package org.noahx.uuid; import org.hibernate.HibernateException;import org.hibernate.engine.SessionImplementor;import org.hibernate.id.IdentifierGenerator; import java.io.Serializable; public class Base64UuidGenerator implements IdentifierGenerator {     @Override    public Serializable generate(SessionImplementor session, Object object) throws HibernateException {        return UuidUtils.compressedUuid();    }}
b、Hibernate4
package org.noahx.uuid; import org.hibernate.HibernateException;import org.hibernate.engine.spi.SessionImplementor;import org.hibernate.id.IdentifierGenerator; import java.io.Serializable; public class Base64UuidGenerator implements IdentifierGenerator {     @Override    public Serializable generate(SessionImplementor session, Object object) throws HibernateException {        return UuidUtils.compressedUuid();    } }
映射中使用Base64的UUID
@Id    @GenericGenerator(name = "uuidGenerator", strategy = "org.noahx.uuid.Base64UuidGenerator")    @GeneratedValue(generator = "uuidGenerator")    @Column("UUID", length = 22)    private String uuid;

 

Base64壓縮UUID長度替換Hibernate原有UUID產生器

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.