目录
UUID生成不重复命名方法
在实际项目中的运用
UUID算法的缺点
什么是雪花算法?
UUID生成不重复命名方法
我们在做项目的时候可能需要用到全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID
UUID可以自动生成唯一的id。是java.util中自带的类
UUID 即统一标识符,是指能够在一台机器上生成的数字,能够保证生成的数字都是唯一的
具体的使用方法如下:
public class UuidTest {
public static void main(String[] args) {
UUID uuid = UUID.randomUUID();
System.out.println(uuid);
}
}
上面程序的输出结果为:
在实际项目中的运用
此方法还可以有效地解决在项目中保存图片的问题,如果保存相同的图片就会产生覆盖的问题,解决方法就是加入此条语句对图片进行重命名,具体的使用如下(以SpringBoot项目为例):
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile fileUpload) {
//获取文件名
String fileName = fileUpload.getOriginalFilename();
//获取文件后缀名。也可以在这里添加判断语句,规定特定格式的图片才能上传,否则拒绝保存。
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//为了避免发生图片替换,这里使用了文件名重新生成
fileName = UUID.randomUUID() + suffixName;
//打印上传相同的图片测试
System.out.println("********"+fileName);
try {
// 将图片保存到文件夹里
fileUpload.transferTo(new File(“保存到的地址”+ fileName));
// 返回文件 Mapping 路径,使用 http://IP:端口/下面返回的路径 ,即可在网页中查看图片
return “本地保存的地址” + fileName;
} catch (Exception e) {
e.printStackTrace();
return null;
}
最终效果如下,上传相同的图片,但是不会出现重复的名字
UUID算法的缺点
但是UUID有一定的缺点:它相对较长,并且一般是无序的
有时候我们希望用一些简单的ID,并且希望ID还能够按着时间有序的生成
这就需要用到雪花算法
什么是雪花算法?
首先算法的名字本身就是Snoflake 意为雪花,世界上没有两片雪花长得一样。因此常称为雪花算法 是Twitter开源的分布式ID生成算法
Twitter雪花算法生成后是一个64bit的long型的数值,它引入了时间戳,可以实现自增
Mybatis-Plus v3.4.2 雪花算法实现类 Sequence,提供了两种构造方法:无参构造,自动生成 dataCenterId 和 workerId;有参构造,创建 Sequence 时明确指定标识位
Sequence的创建无参构造,如何生成dataCenterId 和 workerI
dataCenterId:
public static long getDataCenterId(long maxDatacenterId) {
long id = 1L;
final byte[] mac = NetUtil.getLocalHardwareAddress();
if (null != mac) {
id = ((0x000000FF & (long) mac[mac.length - 2])
| (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6;
id = id % (maxDatacenterId + 1);
}
return id;
}
入参是maxDatacenterId是一个固定值 ,代表着5bit的二进制最大是11111,对应十进制数值31
dataCenterId的取值和Mvc地址有关系、
workerId:
public static long getWorkerId(long datacenterId, long maxWorkerId) {
final StringBuilder mpid = new StringBuilder();
mpid.append(datacenterId);
try {
mpid.append(RuntimeUtil.getPid());
} catch (UtilException igonre) {
//ignore
}
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}
入参 maxWorkderId 也是一个固定值,代表工作机器 ID 最大值,默认值 31;datacenterId 取自上述的 getDatacenterId 方法