UUID(Universally Unique Identifier,通用唯一识别码)是软件开发中常用的一种唯一标识方案,广泛应用于数据库主键、分布式系统ID生成、文件命名、接口请求标识等场景。Java语言内置了对UUID的支持,开发者无需引入额外依赖即可快速生成唯一字符串。
Java中的UUID基于标准规范实现,能够在不同机器、不同时间生成高度不重复的标识。本文将详细介绍Java中UUID的生成方式、常用方法、实际应用场景以及使用时的注意事项。
Java UUID简介
UUID通常由32个十六进制数字组成,中间通过连字符分隔,标准格式如下:
550e8400-e29b-41d4-a716-446655440000一个完整UUID长度为36个字符,其中包含4个短横线。UUID本身由128位数据组成,理论上的重复概率极低,因此适合作为全局唯一标识。
Java提供了java.util.UUID类用于生成和处理UUID,该类从JDK早期版本开始就已经存在,使用非常方便。
引入方式:
import java.util.UUID;使用UUID.randomUUID()生成随机UUID
Java中最常用的UUID生成方式是调用UUID.randomUUID()方法。
示例代码:
public class UUIDDemo {
public static void main(String[] args) {
UUID uuid = UUID.randomUUID();
System.out.println(uuid);
}
}输出结果类似:
c7b9f8d1-5a45-4a8f-9f25-3e6d8b7c2a10randomUUID()生成的是基于随机数算法的UUID,符合UUID Version 4规范,也是目前业务系统中使用最广泛的一种方式。
特点:
不依赖网络环境;
不需要数据库支持;
生成速度快;
重复概率极低;
适合分布式环境。
生成UUID字符串
很多业务场景中并不需要UUID对象,而是需要字符串形式,例如保存到数据库字段或作为接口参数。
可以通过toString()方法转换:
String uuid = UUID.randomUUID().toString();
System.out.println(uuid);结果:
8f2d6c4e-4a21-4f6d-92c8-8f9e5a6b7d11这种格式包含连字符,如果希望生成纯数字字母组合,可以进一步处理。
去除UUID中的横线
部分场景要求UUID长度固定为32位,例如数据库存储或日志追踪,可以去除UUID中的-。
示例:
String uuid = UUID.randomUUID()
.toString()
.replace("-", "");
System.out.println(uuid);输出:
8f2d6c4e4a214f6d92c88f9e5a6b7d11这种方式生成的字符串长度为32位,更适合数据库字段存储。
例如:
CREATE TABLE user_info (
id VARCHAR(32) PRIMARY KEY,
username VARCHAR(50)
);Java保存数据时:
String id = UUID.randomUUID()
.toString()
.replace("-", "");UUID对象常用方法介绍
除了生成UUID,java.util.UUID还提供了一些常用操作方法。
获取UUID高64位和低64位
UUID内部由两个64位long类型数据组成:
UUID uuid = UUID.randomUUID();
long most = uuid.getMostSignificantBits();
long least = uuid.getLeastSignificantBits();
System.out.println(most);
System.out.println(least);这两个方法常用于底层数据处理或特殊存储场景。
根据字符串解析UUID
如果已有UUID字符串,可以转换为UUID对象:
String str = "550e8400-e29b-41d4-a716-446655440000";
UUID uuid = UUID.fromString(str);
System.out.println(uuid);需要注意,传入格式必须符合UUID规范,否则会抛出异常。
错误示例:
UUID.fromString("123456");会导致:
IllegalArgumentExceptionJava生成UUID的实际应用场景
1. 数据库主键生成
在分布式系统中,数据库自增ID可能出现冲突,例如多个服务同时写入数据。
UUID可以作为唯一主键:
String userId = UUID.randomUUID()
.toString()
.replace("-", "");优势:
不依赖数据库自增;
多服务同时生成不会冲突;
支持数据提前生成。
不足:
UUID长度较长;
索引占用空间较大;
查询性能可能低于数字类型ID。
2. 文件唯一命名
上传文件时,为避免文件名重复,可以使用UUID:
String filename = UUID.randomUUID() + ".jpg";生成:
f8e9d7c6-1234-4567-8901-demo.jpg适用于:
图片上传;
视频存储;
临时文件生成。
3. 分布式系统请求追踪
微服务架构中,一个请求可能经过多个服务,可以使用UUID作为Trace ID。
例如:
requestId=9ab23c45-678d-4321-a123-789456def000通过日志关联,可以快速定位问题。
4. 临时业务编号
例如订单处理中生成临时交易编号:
String orderNo = UUID.randomUUID()
.toString()
.replace("-", "");适合:
支付流水号;
任务编号;
消息唯一标识。
UUID与数据库自增ID对比
| 特性 | UUID | 自增ID |
|---|---|---|
| 唯一性 | 极高 | 单库内唯一 |
| 分布式支持 | 优秀 | 较弱 |
| 存储空间 | 较大 | 较小 |
| 索引效率 | 较低 | 较高 |
| 可读性 | 较差 | 较好 |
如果系统规模较小,并且数据集中管理,自增ID通常更高效。
如果是分布式系统、多数据源环境,UUID更加灵活。
UUID使用中的注意事项
1. 不建议直接作为高频查询字段
UUID随机性较强,会导致数据库索引随机写入,可能影响B+树结构维护效率。
对于高并发业务,可以考虑:
雪花算法ID;
时间有序UUID;
分布式ID生成服务。
2. 注意字段长度设计
UUID标准格式:
36字符去除横线:
32字符数据库设计时需要合理设置字段类型。
例如:
id CHAR(32)通常比:
id VARCHAR(36)更节省空间。
3. 避免重复生成
UUID虽然重复概率极低,但业务代码中仍应避免无意义重复创建。
例如:
String id = UUID.randomUUID().toString();
save(id);
sendMessage(id);应保持同一个业务流程使用同一个UUID。
Java UUID生成工具类封装
项目开发中,可以封装一个工具类方便调用:
public class UUIDUtil {
public static String generateUUID() {
return UUID.randomUUID()
.toString()
.replace("-", "");
}
public static void main(String[] args) {
System.out.println(generateUUID());
}