Java生成唯一id的几种方式(已验证) 您所在的位置:网站首页 id中的框架类型 Java生成唯一id的几种方式(已验证)

Java生成唯一id的几种方式(已验证)

#Java生成唯一id的几种方式(已验证)| 来源: 网络整理| 查看: 265

1.数据库自增序列方式 数据库方式比较简单,比如oracle可以用序列生成id,Mysql中的AUTO_INCREMENT等,这样可以生成唯一的ID,性能和稳定性依赖于数据库!如mysql主键递增: 在这里插入图片描述 2.系统时间戳 这种方式每秒最多一千个,如果是单体web系统集群部署方式,可以为每台机器加个标识!(并发量较大不建议使用)

/** * 根据时间戳生成唯一id */ @Test public void test(){ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSSS"); String id = sdf.format(System.currentTimeMillis()); System.out.println("id:"+id); //id:202010221400070793 }

3.UUID uuid生成全球唯一id,生成简单粗暴,本地生成,没有网络开销,效率高;但是长度较长无规律,不易维护!(不建议作为数据库主键)

/** * 用uuid生成为id */ @Test public void testUUID(){ String uuid = UUID.randomUUID().toString(); System.out.println("uuid:"+uuid); //uuid:49abc3f3-d6cc-4401-b24a-0fc808d1b594 }

4.雪花算法 SnowFlake算法生成id的结果是一个64bit大小的Long类型, 本地生成,没有网络开销,效率高,但是依赖机器时钟

public class SnowflakeIdWorker { // ==============================Fields=========================================== /** 开始时间截 (2015-01-01) */ private final long twepoch = 1420041600000L; /** 机器id所占的位数 */ private final long workerIdBits = 5L; /** 数据标识id所占的位数 */ private final long datacenterIdBits = 5L; /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */ private final long maxWorkerId = -1L ^ (-1L throw new IllegalArgumentException(String.format ("worker Id can't be greater than %d or less than 0", maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId long timestamp = timeGen(); //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常 if (timestamp sequence = (sequence + 1) & sequenceMask; //毫秒内序列溢出 if (sequence == 0) { //阻塞到下一个毫秒,获得新的时间戳 timestamp = tilNextMillis(lastTimestamp); } } //时间戳改变,毫秒内序列重置 else { sequence = 0L; } //上次生成ID的时间截 lastTimestamp = timestamp; //移位并通过或运算拼到一起组成64位的ID return ((timestamp - twepoch) timestamp = timeGen(); } return timestamp; } /** * 返回以毫秒为单位的当前时间 * @return 当前时间(毫秒) */ protected long timeGen() { return System.currentTimeMillis(); } //==============================Test============================================= /** 测试 */ public static void main(String[] args) { SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0); long id = idWorker.nextId(); System.out.println("id:"+id); //id:768842202204864512 } }

5.Redis生成全局唯一id 基于redis单线程的原子性特点生成全局唯一id,redis性能高,支持集群分片,唯一缺点就是依赖redis服务(推荐使用) 实现过程(核心代码):

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.util.Calendar; import java.util.Date; /** * @author xf * @version 1.0.0 * @ClassName PrimaryKeyUtil * @Description TODO 利用redis生成数据库全局唯一性id * @createTime 2020.10.22 10:42 */ @Service public class PrimaryKeyUtil { @Autowired private RedisTemplate redisTemplate; /** * 获取年的后两位加上一年多少天+当前小时数作为前缀 * @param date * @return */ public String getOrderIdPrefix(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int day = calendar.get(Calendar.DAY_OF_MONTH); int hour = calendar.get(Calendar.HOUR_OF_DAY); //String.format("%1$02d", var) // %后的1指第一个参数,当前只有var一个可变参数,所以就是指var。 // $后的0表示,位数不够用0补齐,如果没有这个0(如%1$nd)就以空格补齐,0后面的n表示总长度,总长度可以可以是大于9例如(%1$010d),d表示将var按十进制转字符串,长度不够的话用0或空格补齐。 String monthFormat = String.format("%1$02d", month+1); String dayFormat = String.format("%1$02d", day); String hourFormat = String.format("%1$02d", hour); return year + monthFormat + dayFormat+hourFormat; } /** * 生成订单号 * @param prefix * @return */ public Long orderId(String prefix) { String key = "ORDER_ID_" + prefix; String orderId = null; try { Long increment = redisTemplate.opsForValue().increment(key,1); //往前补6位 orderId=prefix+String.format("%1$06d",increment); } catch (Exception e) { System.out.println("生成单号失败"); e.printStackTrace(); } return Long.valueOf(orderId); } }

测试redis生成唯一id,生成1000耗时514毫秒

import com.king.science.util.PrimaryKeyUtil; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.Date; /** * 测试类 */ @SpringBootTest class ScienceApplicationTests { @Autowired private PrimaryKeyUtil primaryKeyUtil; /** * 使用redis生成唯一id */ @Test public void testRedis() { long startMillis = System.currentTimeMillis(); String orderIdPrefix = primaryKeyUtil.getOrderIdPrefix(new Date()); //生成单个id //Long aLong = primaryKeyUtil.orderId(orderIdPrefix); for (int i = 0; i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有