MyBatis-Plus主键生成策略 IdType.ASSIGN_ID
所属分类 mybatis
浏览量 8
MyBatis-Plus 中,
IdType.ASSIGN_ID 基于 Twitter 的 Snowflake 算法,
用于生成全局唯一的 64 位 Long 类型 ID
通过 Snowflake 算法,
IdType.ASSIGN_ID 提供了一种高效、可靠的分布式主键生成方案,
是 MyBatis-Plus 中推荐的主键策略之一。
生成的 ID 是一个 64 位的 Long 型数字
位数 含义 说明
1 符号位 固定为 0,表示正数
41 时间戳(毫秒) 表示从自定义起始时间(如 2016-01-01)到当前时间的毫秒数
10 机器/节点 ID 标识生成 ID 的机器或节点,通常在分布式系统中唯一
12 序列号(Sequence) 同一毫秒内生成的 ID 序列号,从 0 开始递增
@TableId(type = IdType.ASSIGN_ID)
// @TableId(type = IdType.AUTO)
private Long id;
使用 @TableId(type = IdType.ASSIGN_ID) 时,在插入数据前会自动调用 Snowflake 算法生成 ID
起始时间戳:默认从 2016-01-01 00:00:00 开始计算(可自定义)
生成 ID 的步骤
获取当前时间戳:
计算从起始时间到当前时间的毫秒数(41 位)
处理时间回拨:
如果当前时间戳小于上次生成 ID 的时间戳,抛出异常(避免重复 ID)
如果时间回拨在可接受范围内(如 < 5ms),等待时间追上;否则抛出异常
生成序列号:
同一毫秒内,序列号递增(12 位最大值为 4095)
组合 ID:
将时间戳、机器 ID 和序列号按位拼接,生成最终的 64 位 Long 型 ID
核心代码
com.baomidou.mybatisplus.core.toolkit.IdWorker
public class IdWorker {
private static IdentifierGenerator IDENTIFIER_GENERATOR = new DefaultIdentifierGenerator();
public static final DateTimeFormatter MILLISECOND = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
public IdWorker() {
}
public static long getId() {
return getId((Object)null);
}
public static long getId(Object entity) {
return IDENTIFIER_GENERATOR.nextId(entity).longValue();
}
public static String getIdStr() {
return getIdStr((Object)null);
}
public static String getIdStr(Object entity) {
return IDENTIFIER_GENERATOR.nextId(entity).toString();
}
public static String getMillisecond() {
return LocalDateTime.now().format(MILLISECOND);
}
public static String getTimeId() {
return getMillisecond() + getIdStr();
}
public static void initSequence(long workerId, long dataCenterId) {
IDENTIFIER_GENERATOR = new DefaultIdentifierGenerator(workerId, dataCenterId);
}
public static void setIdentifierGenerator(IdentifierGenerator identifierGenerator) {
IDENTIFIER_GENERATOR = identifierGenerator;
}
public static String get32UUID() {
ThreadLocalRandom random = ThreadLocalRandom.current();
return (new UUID(random.nextLong(), random.nextLong())).toString().replace("-", "");
}
}
优势与局限性
优势
全局唯一:
结合时间戳、机器 ID 和序列号,确保分布式系统中生成的 ID 不重复
无中心依赖:
不依赖数据库自增或第三方服务,适合微服务架构
有序性:
ID 与时间戳相关,大致按时间递增(适合日志、分库分表场景)
局限性
时间回拨问题:
系统时间回拨可能导致 ID 重复或生成失败(需额外处理)
机器 ID 限制:
10 位机器 ID 最多支持 1024 个节点(可通过调整位数扩展)
不支持字符串 ID:
生成的 ID 是 Long 类型,不适合需要字符串格式的场景(如 UUID)
实际应用建议
机器 ID 分配:
在分布式环境中,需为每个节点分配唯一的机器 ID(如通过配置中心或注册中心动态分配)
时间回拨处理:
在服务器时间同步时,可能需要暂停服务或使用 NTP 服务调整时间
字段类型匹配:
数据库主键字段需为 BIGINT 或 NUMBER(20) 等支持大整数的类型
上一篇
下一篇
技术分析四要素:量价时空
光伏边缘一体机AE功能解析
均线战法口诀
裸K线口诀