mybatisPlus主键策略解读

目录

主键生成策略介绍

AUTO策略

INPUT策略

ASSIGN_ID策略

NONE策略

ASSIGN_UUID策略


主键生成策略介绍

主键的作用就是唯一标识,我们可以通过这个唯一标识来定位到这条数据。当然对于表数据中的主键,我们可以自己设计生成规则,生成主键。但是在更多的场景中,没有特殊要求的话,我们每次自己手动生成的比较麻烦,我们可以借助框架提供好的主键生成策略,来生成主键。这样比较方便快捷

在MybatisPlus中提供了一个注解,是@TableId,该注解提供了各种的主键生成策略,我们可以通过使用该注解来对于新增的数据指定主键生成策略。那么在以后新增数据的时候,数据就会按照我们指定的主键生成策略来生成对应的主键。

java 复制代码
@TableName("sys_user")
public class User {
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
属性 类型 必须指定 默认值 描述
value String "" 主键字段名
type Enum IdType.NONE 指定主键类型

type类型如下

描述
AUTO 数据库 ID 自增
NONE 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUT insert 前自行 set 主键值
ASSIGN_ID 分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID 分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)
ID_WORKER 分布式全局唯一 ID 长整型类型(please use ASSIGN_ID)
UUID 32 位 UUID 字符串(please use ASSIGN_UUID)
ID_WORKER_STR 分布式全局唯一 ID 字符串类型(please use ASSIGN_ID)

AUTO策略

该策略为跟随数据库表的主键递增策略,前提是数据库表的主键要设置为自增

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
java 复制代码
@Test
void primaryKey(){
    User user = new User();
    user.setName("Mary");
    user.setAge(35);
    user.setEmail("[email protected]");
    userMapper.insert(user);
}

INPUT策略

该策略表示,必须由我们手动的插入id,否则无法添加数据

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.INPUT)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

这里如果我们省略不写id,会发现,无法插入数据

java 复制代码
@Test
void primaryKey(){
    User user = new User();
    user.setName("Jerry");
    user.setAge(38);
    user.setEmail("[email protected]");
    userMapper.insert(user);
}

但是我们自己指定了id,发现可以添加成功

ASSIGN_ID策略

我们来思考一下,像之前这种自动递增的方式,有什么问题?

如果我们将来一张表的数据量很大,我们需要进行分表。

常见的分表策略有两种

【1】水平拆分

水平拆分就是将一个大的表按照数据量进行拆分

【2】垂直拆分

垂直拆分就是将一个大的表按照字段进行拆分

其实我们对于拆分后的数据,有三点需求,就拿水平拆分来说:

【1】之前的表的主键是有序的,拆分后还是有序的

【2】虽然做了表的拆分,但是每条数据还需要保证主键的唯一性

【3】主键最好不要直接暴露数据的数量,这样容易被外界知道关键信息

那就需要有一种算法,能够实现这三个需求,这个算法就是雪花算法

雪花算法是由一个64位的二进制组成的,最终就是一个Long类型的数值。主要分为四部分存储

【1】1位的符号位,固定值为0

【2】41位的时间戳

【3】10位的机器码,包含5位机器id和5位服务id

【4】12位的序列号

使用雪花算法可以实现有序、唯一、且不直接暴露排序的数字。

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

NONE策略

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.NONE)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

NONE策略表示不指定主键生成策略,当我们没有指定主键生成策略或者主键策略为NONE的时候,他跟随的是全局策略,全局配置中 id-type是用于配置主键生成策略的,我们可以看一下id-type的默认值

通过查看源码发现,id-type的默认值就是雪花算法

ASSIGN_UUID策略

UUID(Universally Unique Identifier)全局唯一标识符,定义为一个字符串主键,采用32位数字组成,编码采用16进制,定义了在时间和空间都完全唯一的系统信息。

UUID的编码规则:

【1】1~8位采用系统时间,在系统时间上精确到毫秒级保证时间上的唯一性;

【2】9~16位采用底层的IP地址,在服务器集群中的唯一性;

【3】17~24位采用当前对象的HashCode值,在一个内部对象上的唯一性;

【4】25~32位采用调用方法的一个随机数,在一个对象内的毫秒级的唯一性。

通过以上4种策略可以保证唯一性。在系统中需要用到随机数的地方都可以考虑采用UUID算法。

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.ASSIGN_UUID)
    private String id;
    private String name;
    private Integer age;
    private String email;
}
相关推荐
论迹1 分钟前
【JavaEE】-- HTTPS
java·https·java-ee
天天摸鱼的java工程师2 分钟前
面试官灵魂拷问:如何设计一个支持 10 万 QPS 的秒杀系统?
java·后端·面试
martian6652 分钟前
达梦数据库中无效触发器的排查与解决方案指南
开发语言·数据库
无名之逆2 分钟前
Junior Year Self-Study Notes My Journey with the Hyperlane Framework
java·开发语言·前端·spring boot·后端·rust·编程
crud2 分钟前
Spring Boot 整合 Smart-Doc:零注解生成 API 文档,告别 Swagger
java·spring boot·swagger
网硕互联的小客服4 分钟前
RAID 阵列有哪些?分别有什么作用?
运维·服务器·网络·数据库·网络安全·raid
-逐鹿中原4 分钟前
开源PSS解析器
java·测试用例
武子康10 分钟前
Java-43 深入浅出 Nginx - 基本配置方式 nginx.conf Events块 HTTP块 反向代理 负载均衡
java·后端·nginx·http·负载均衡·运维开发
界面开发小八哥12 分钟前
「Java EE开发指南」如何用MyEclipse创建一个WEB项目?(一)
java·ide·java-ee·eclipse·myeclipse
neo_尼欧15 分钟前
DevEco Studio 报错 “too many restarts of gpu-process (jcef)“
java·服务器·前端