本文来自http://my.oschina.net/noahxiao/blog/132277,个人储藏使用

1、背景

在采用Hibernate做对象映射时,我一直都采用UUID来做主键。由于Hibernate的UUID需要占用32位的字符,所以一般都会让人感觉响效率且增加存储占用。

我在查看公司项目时发现了一种比较好的生成UUID的方法,就是将UUID数据进行Base64化。觉得比较有意义拿出来给大家分享。

2、传统UUID

a、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生成器的更多相关文章

  1. SAS学习笔记62 通过压缩变量长度来实现数据集压缩

    有时候从其他数据库过来的字符型变量Length很长,导致数据集文件很大,可以通过压缩变量长度来实现数据集压缩 具体思路: LENGTH语句设置所有变量真实长度 SET数据集的时候对原有变量进行RENA ...

  2. php中按指定标识及长度替换字符的方法代码

    /** * 按指定标识及长度替换字符 * @param $str * @param int $start 开始的位数 * @param int $end 后面保留的位数 * @param string ...

  3. [py]Python使用UUID库生成唯一ID(uuid模块)

    https://www.cnblogs.com/dkblog/archive/2011/10/10/2205200.html uuid介绍 UUID是128位的全局唯一标识符,通常由32字节的字符串表 ...

  4. 如何压缩UUID长度?

    java中UUID的toString方法,生成的uuid是36位了,在项目中,有时候会显的过长,占用空间比较多,如何能够压缩存储下,又能够保证uuid的唯一性呢? 一. 思路 看源码后,发现UUID的 ...

  5. 图片采用base64压缩,可以以字符串的形式传送base64给服务端转存为图片

    (function () { var coverImage = document.querySelector('<div id="coverImage">file< ...

  6. 蓝牙UUID——Android各种蓝牙设备的UUID

    本文转自:http://www.14blog.com/archives/481 UUID是“Universally Unique Identifier”的简称,通用唯一识别码的意思.对于蓝牙设备,每个 ...

  7. base64 压缩图片

    //图片处理 afterimg(err, photos) { var _this = this; if(err && err != null && err != '') ...

  8. Python uuid库中 几个uuid的区别

    在用到uuid库的时候,发现uuid有很多个,比较好奇,就查了一下他们的区别 uuid1()——基于时间戳 uuid2()——基于分布式计算环境DCE(Python中没有这个函数) uuid3()—— ...

  9. gulp之css,js压缩合并加密替换

    为了防止客户端的静态资源缓存,我们需要每次更新css或js的时候,通过md5或时间戳等方式重新命名静态资源.让客户端可以重新请求资源,而不是从缓存里取.然后html模板里的src也要做相应的修改.当然 ...

随机推荐

  1. SpringMVC的@RequestParam

    以前写controller层的时候都是默认带上 @RequestParam 的, 今天发现不加@RequestParam 也能接收到参数 下面我们来区分一下加与不加的区别 这里有两种写法 @Reque ...

  2. java7(2)——使用mutilcatch注意事项

    从java7推出mutilcatch后,到现在都少有看到人使用,可能是这个功能真正用起来,比起多个catch并不快多少,而且现在的工IDE具太厉害了,什么都有快捷键!说是这么说,我们还是得了解一下如何 ...

  3. redis_cluster部署过程

    Redis集群1.多个redis节点网络互联,数据共享2.所有的节点都是一主一从(可以是多个从),其中从不提供服务3.不支持同时处理多个键(如mset/mget),因为redis需要把键均匀分布在各个 ...

  4. .globl分析

    Uboot中常看到.globl .globl _start _start: b reset .align .globl _TEXT_BASE _TEXT_BASE: .globl _start  /* ...

  5. DecisionTree

    1.信息增益的定义,也就是互信息 2.信息增益的推导 由公式即可得到信息增益 信息增益存在偏向于选择取值较多的特征的问题,信息增益比可以对这一问题进行修正 3.信息增益比 4.基尼指数,基尼指数越大, ...

  6. Linux系统——shell脚本

    shell脚本编程 作用:通过命令行解析的方式,自动执行设定好的程序或命令代码.(若将脚本挂到定时任务中,就会自动在非工作时间里自动触发执行程序) Shell脚本文件以“.sh”结尾 规范的Shell ...

  7. html-4, form 表单 输入、传文件、单选、多选、下拉菜单、文本描述、重置、submit、按钮限制输入

    <!-- form HTTP协议 action:提交的服务器网址 method:get(默认)| post(应用:登录注册.上传文件) 页面中的a img link 默认是get请求 input ...

  8. sgu 103 Traffic Lights 解题报告及测试数据

    103. Traffic Lights Time limit per test: 0.25 second(s) Memory limit: 4096 kilobytes 题解: 1.其实就是求两点间的 ...

  9. scala drools and map

    需求,安全检查,例如Linux系统,用户安全检查,配置项检查等,这些检查的规则在Drools里面去实现,数据传送过来即可, 问题:如何定义数据结构,不同的检查项会有不同的数据结构,如何规范呢? 思路: ...

  10. struct2的xml文件中result的配置(转)

    一个result代表了一个可能的输出.当Action类的方法执行完成时,它返回一个字符串类型的结果码,框架根据这个结果码选择对应的result,向用户输出.在com.opensymphony.xwor ...