MyBatis-Plus 主键生成策略
接上一篇博客:快速上手 MyBatis-Plus 开发
在测试类中执行 Insert 操作,向数据表中插入记录:
//测试插入操作
@Test
public void testInsert(){
User user = new User();
user.setName("Cloud");
user.setAge(3);
user.setEmail("12265663@qq.com"); //MP自动生成id
int res = userMapper.insert(user);
System.out.println(res); //受影响的行数
System.out.println(user);
}
通过控制台打印的日志发现,MyBatis-Plus 自动为 user
对象的 id
属性赋值,赋值采用的是雪花算法;
@TableId
:设置主键映射,value
映射主键字段名,type
设置主键类型,即主键的生成策略。比如:@TableId(value = "id", type = IdType.AUTO)
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.Auto)
private Long id;
private String name;
private Integer age;
private String email;
}
IdType
是枚举类,主要有 4 种不同类型的取值(AUTO、NONE、INPUT、ASSIGN_ID 和 ASSIGN_UUID),源码如下:
public enum IdType {
AUTO(0),
NONE(1),
INPUT(2),
ASSIGN_ID(3),
ASSIGN_UUID(4),
//下面的表示已经弃用了,并以上面几种代替
/** @deprecated */
@Deprecated
ID_WORKER(3),
/** @deprecated */
@Deprecated
ID_WORKER_STR(3),
/** @deprecated */
@Deprecated
UUID(4);
}
值 | 描述 |
---|---|
AUTO | 主键字段自增 |
NONE | 未设置主键 |
INPUT | 需要开发者手动赋值 |
ASSIGN_ID | MP 分配 ID,Number / String 类型 |
ASSIGN_UUID | MP 分配 UUIN,String 类型 |
1、AUTO:主键字段自增
① 实体类的主键字段的注解 @TableId(type = IdType.AUTO)
;
② 数据表对应的字段一定也要设置成自增;
如果只加了注解,但没有将数据表对应的主键字段设置为自增,则将会出现如下的异常!
注意:使用 type = IdType.AUTO
注解时,一定要将其对应的主键字段设置为【自增】。
2、NONE:未设置主键
由于每一张数据表都是有主键的,因此几乎没有添加该注解的必要。
3、INPUT:需要开发者手动赋值
INPUT 如果开发者没有手动赋值,则数据库通过设置自增方式给主键赋值(MP不介入主键生成),同样地,如果数据库也没有设置自增则会抛出异常;如果开发者手动赋值,则直接存入该值。
可以看到 user
对象的主键 id
值为 null
,但该对象被成功插入到数据库中,是因为数据库设置了主键自增的策略。
牢记一点:@TableId=(type = IdType.INPUT )
注解下 MyBatis-Plus 不介入主键生成。
4、ASSIGN_ID:MyBatis-Plus 自动赋值
ASSIGN_ID 如果用户或开发者没有为主键赋值,则由 MyBatis-Plus 采用 snowflake 算法(也被称为雪花算法)为主键字段分配一个ID,这个 ID 可以是 Number(Long) 类型,也可以是 String 类型。
雪花算法:snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为 毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味 着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。可以保证几乎全球唯 一!
如果不为主键添加 @TableId
注解,其默认为 @TableId=(type = IdType.ID_WORKER)
,由于这个枚举项已经被弃用了,并使用了 ASSIGN_ID
代替。如果这个时候用户不为主键赋值,那么 MP 会自动赋值,而此时数据库主键字段是否被设置自增也没有必要。
5、ASSIGN_UUID:MyBatis-Plus 分配 UUID,必须是 String 类型
ASSIGN_UUID 的用法与 ASSIGN_ID 类似,可以表示更长的唯一的 ID,但其主键的数据类型必须是 String,由 MyBatis-Plus 自动生成 UUID 进行赋值;
6、总结
由于数据表的主键字段不能为空,主键生成策略的一般规则如下:
如果用户或开发者为主键赋值,则直接存入该值;若用户没有为主键赋值,则由 MP(MyBatis-Plus 的简称) 为主键赋值;若用户和 MP 都没有给主键设定值,则由数据库的数据表设置主键自增来完成赋值操作;如果用户、MyBatis-Plus 以及数据库都没有给主键赋值,则程序就会抛出异常。