refactor(jpa): 将 Snowflake ID 生成逻辑抽取为公共工具类
This commit is contained in:
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.lanyuanxiaoyao.service.template.jpa.entity;
|
package com.lanyuanxiaoyao.service.template.jpa.entity;
|
||||||
|
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.helper.SnowflakeHelper;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.Instant;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.id.IdentifierGenerator;
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
@@ -11,75 +11,10 @@ public class SnowflakeIdGenerator implements IdentifierGenerator {
|
|||||||
@Override
|
@Override
|
||||||
public Serializable generate(SharedSessionContractImplementor session, Object object) {
|
public Serializable generate(SharedSessionContractImplementor session, Object object) {
|
||||||
try {
|
try {
|
||||||
return Snowflake.next();
|
return SnowflakeHelper.next();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Generate snowflake id failed", e);
|
log.error("Generate snowflake id failed", e);
|
||||||
throw new RuntimeException(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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user