MyBatis-Plus默认使用ASSIGN_ID(雪花算法)生成64位有序唯一ID,实体类标注@TableId(type=IdType.ASSIGN_ID)、字段类型为Long或String,数据库对应BIGINT或VARCHAR(20),无需数据库自增;ASSIGN_UUID生成32位无序UUID,类型必须String,数据库用VARCHAR(32);原生MyBatis需手动处理ID生成。

MyBatis 本身不直接生成主键,真正承担 UUID 或雪花 ID 生成职责的是 MyBatis-Plus(MP),它在插入前自动填充主键值。标准 MyBatis 需要手动 set ID 或借助插件/拦截器;而 MP 提供开箱即用的策略支持,只需配置得当即可无缝使用。
使用雪花算法(推荐分布式场景)
MyBatis-Plus 自 3.3.0 起默认采用 ASSIGN_ID(即雪花算法),适用于大多数微服务架构:
- 实体类主键字段标注
@TableId(type = IdType.ASSIGN_ID),类型可为Long或String - 数据库对应列建议用
BIGINT(Long)或VARCHAR(20)(String,足够存 19 位数字) - 无需数据库自增设置,也不依赖数据库序列或触发器
- 生成的 ID 是 64 位整数,时间有序、全局唯一、高性能
使用 UUID(适合强唯一性但不强调顺序)
若更看重绝对随机性和跨系统兼容性,可选 UUID:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 实体类字段标注
@TableId(type = IdType.ASSIGN_UUID),类型必须为String - 数据库列定义为
VARCHAR(32)(不含中划线的 32 位十六进制字符串) - ID 无序,对 B+ 树索引有一定影响(可能引发页分裂),但完全规避时钟回拨与节点协调问题
MyBatis 原生方式(无 MP 时)
纯 MyBatis 不提供内置 ID 生成器,需自行处理:
立即学习“Java免费学习笔记(深入)”;
- 插入前在业务层调用
UUID.randomUUID().toString().replace("-", "")或引入 Snowflake 工具类(如DefaultIdentifierGenerator)生成 ID 并 set 到对象 - 或编写 MyBatis 插件,拦截
Executor.update,扫描@Insert方法参数中的主键字段,自动注入 - 也可在 XML 的
<insert>中用<selectKey>调用数据库函数(如 MySQL 的UUID()),但仅限 UUID,且丧失雪花算法的时间有序优势
注意事项与常见坑
实际落地时需关注几个关键点:
- 主键字段不能为
NOT NULL且无默认值,同时 Java 层未赋值 → 插入会报错(MP 默认策略只在 insert 时填充,不干预 null 判断) - 雪花 ID 在多 JVM 实例下需确保机器号(workerId)不重复,MP 默认基于 IP + 进程号生成,但高可用部署建议显式配置
spring.datasource.dynamic.strategy.default.worker-id类似参数(取决于你用的 MP 扩展或自定义配置) - 若升级 MP 版本到 3.5.0+,
ID_WORKER和ID_WORKER_STR已被标记废弃,统一用ASSIGN_ID - 批量插入(
saveBatch)同样生效,每个对象的 ID 独立生成,无需额外处理

















