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("test7@powernode.com");
    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("test8@powernode.com");
    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;
}
相关推荐
2601_9638699544 分钟前
【计算机毕业设计】基于 Spring Boot+Vue的手工体验馆管理系统的设计与实现
java·spring boot·后端
曹牧1 小时前
Java:BeanListHandler
java·数据库·oracle
ITenderL3 小时前
MySQL联合索引遇到范围查询
数据库·索引
白鸽(二般)8 小时前
MinIO Java Client API
java·开发语言
敲个大西瓜8 小时前
Redis一百道核心面试题
数据库·redis·缓存
阿里云大数据AI技术8 小时前
EMR Serverless Spark AI Function 的双维降本实践
人工智能·sql·spark
软萌萌的18 小时前
Java Spring Boot 修改yml配置&加载顺序规则
java·spring boot·python
IT小盘9 小时前
13-企业Prompt模板-角色任务约束与输出格式
java·前端·prompt
爱敲键盘的猴子9 小时前
Java并发编程 -- volatile
java·java并发
plainGeekDev11 小时前
工厂模式 → Hilt
android·java·kotlin