From 5bf6e9ecdc17140ccd4920f36b3c772fee6b01d1 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Wed, 7 Jan 2026 09:47:42 +0800 Subject: [PATCH] =?UTF-8?q?refactor(jpa):=20=E5=B0=86=20Snowflake=20ID=20?= =?UTF-8?q?=E7=94=9F=E6=88=90=E9=80=BB=E8=BE=91=E6=8A=BD=E5=8F=96=E4=B8=BA?= =?UTF-8?q?=E5=85=AC=E5=85=B1=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/helper/SnowflakeHelper.java | 68 ++++++++++++++++++ .../jpa/entity/SnowflakeIdGenerator.java | 69 +------------------ 2 files changed, 70 insertions(+), 67 deletions(-) create mode 100644 spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/helper/SnowflakeHelper.java diff --git a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/helper/SnowflakeHelper.java b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/helper/SnowflakeHelper.java new file mode 100644 index 0000000..529c763 --- /dev/null +++ b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/helper/SnowflakeHelper.java @@ -0,0 +1,68 @@ +package com.lanyuanxiaoyao.service.template.common.helper; + +import java.time.Instant; + +public class SnowflakeHelper { + /** + * 起始的时间戳 + */ + private final static long START_TIMESTAMP = 1; + + /** + * 序列号占用的位数 + */ + private final static long SEQUENCE_BIT = 11; + + /** + * 序列号最大值 + */ + private final static long MAX_SEQUENCE_BIT = ~(-1 << SEQUENCE_BIT); + + /** + * 时间戳值向左位移 + */ + private final static long TIMESTAMP_OFFSET = SEQUENCE_BIT; + + /** + * 序列号 + */ + private static long sequence = 0; + /** + * 上一次时间戳 + */ + private static long lastTimestamp = -1; + + public static synchronized long next() { + long currentTimestamp = nowTimestamp(); + if (currentTimestamp < lastTimestamp) { + throw new RuntimeException("Clock have moved backwards."); + } + + if (currentTimestamp == lastTimestamp) { + // 相同毫秒内, 序列号自增 + sequence = (sequence + 1) & MAX_SEQUENCE_BIT; + // 同一毫秒的序列数已经达到最大 + if (sequence == 0) { + currentTimestamp = nextTimestamp(); + } + } else { + // 不同毫秒内, 序列号置为0 + sequence = 0; + } + + lastTimestamp = currentTimestamp; + return (currentTimestamp - START_TIMESTAMP) << TIMESTAMP_OFFSET | sequence; + } + + private static long nextTimestamp() { + long milli = nowTimestamp(); + while (milli <= lastTimestamp) { + milli = nowTimestamp(); + } + return milli; + } + + private static long nowTimestamp() { + return Instant.now().toEpochMilli(); + } +} diff --git a/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/entity/SnowflakeIdGenerator.java b/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/entity/SnowflakeIdGenerator.java index 7ed796d..af8f71d 100644 --- a/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/entity/SnowflakeIdGenerator.java +++ b/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/entity/SnowflakeIdGenerator.java @@ -1,7 +1,7 @@ package com.lanyuanxiaoyao.service.template.jpa.entity; +import com.lanyuanxiaoyao.service.template.common.helper.SnowflakeHelper; import java.io.Serializable; -import java.time.Instant; import lombok.extern.slf4j.Slf4j; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.IdentifierGenerator; @@ -11,75 +11,10 @@ public class SnowflakeIdGenerator implements IdentifierGenerator { @Override public Serializable generate(SharedSessionContractImplementor session, Object object) { try { - return Snowflake.next(); + return SnowflakeHelper.next(); } catch (Exception e) { log.error("Generate snowflake id failed", e); throw new RuntimeException(e); } } - - public static class Snowflake { - /** - * 起始的时间戳 - */ - private final static long START_TIMESTAMP = 1; - - /** - * 序列号占用的位数 - */ - private final static long SEQUENCE_BIT = 11; - - /** - * 序列号最大值 - */ - private final static long MAX_SEQUENCE_BIT = ~(-1 << SEQUENCE_BIT); - - /** - * 时间戳值向左位移 - */ - private final static long TIMESTAMP_OFFSET = SEQUENCE_BIT; - - /** - * 序列号 - */ - private static long sequence = 0; - /** - * 上一次时间戳 - */ - private static long lastTimestamp = -1; - - public static synchronized long next() { - long currentTimestamp = nowTimestamp(); - if (currentTimestamp < lastTimestamp) { - throw new RuntimeException("Clock have moved backwards."); - } - - if (currentTimestamp == lastTimestamp) { - // 相同毫秒内, 序列号自增 - sequence = (sequence + 1) & MAX_SEQUENCE_BIT; - // 同一毫秒的序列数已经达到最大 - if (sequence == 0) { - currentTimestamp = nextTimestamp(); - } - } else { - // 不同毫秒内, 序列号置为0 - sequence = 0; - } - - lastTimestamp = currentTimestamp; - return (currentTimestamp - START_TIMESTAMP) << TIMESTAMP_OFFSET | sequence; - } - - private static long nextTimestamp() { - long milli = nowTimestamp(); - while (milli <= lastTimestamp) { - milli = nowTimestamp(); - } - return milli; - } - - private static long nowTimestamp() { - return Instant.now().toEpochMilli(); - } - } }