首页 > 其他分享 >Mybatis-Plus主键生成策略详解

Mybatis-Plus主键生成策略详解

时间:2022-12-07 19:31:09浏览次数:67  
标签:IdType 生成器 主键 public Plus Mybatis ID id


文章目录

  • ​​前言​​
  • ​​一、官网​​
  • ​​二、主键注解@TableId说明​​
  • ​​1、源码​​
  • ​​2、作用​​
  • ​​3、使用​​
  • ​​三、主键生成策略-IdType枚举说明​​
  • ​​1、源码​​
  • ​​2、说明​​
  • ​​3、全局设置​​
  • ​​三、ID生成器介绍​​
  • ​​1、IdentifierGenerator​​
  • ​​2、IKeyGenerator​​
  • ​​四、自定义主键生成器​​
  • ​​总结​​

前言

很多人在使用Mybatis-Plus的时候可能会疑惑,自己明明没有配置主键的生成策略,但是执行新增操作时却自动生成了主键,而且还特别长。这是由于Mybatis-Plus默认就会采用雪花算法填充主键字段。

今天就和大家详解聊聊Mybatis-Plus中主键生成的相关策略。


一、官网

Mybatis-Plus主键策略:​​https://baomidou.com/pages/e131bd/​

Mybatis-Plus自定义ID生成器:​​https://baomidou.com/pages/568eb2/​

TIP⚠️:
推荐学习框架的时候,多研究下官网,获取第一手资料。

二、主键注解@TableId说明

1、源码

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableId {
String value() default "";

IdType type() default IdType.NONE;
}

Mybatis-Plus主键生成策略详解_主键

2、作用

  1. 标识主键字段
    使用@TableId可以标识实体对象中和数据库表中主键对应的字段。如果不添加@TableId注解,会默认匹配id字段为主键。
  2. 变量名称和主键字段名称的匹配
    如果表中的主键字段名称和实体中的主键字段名称不相同,这时候就要通过@TableId中的value属性明确指出对应的数据库主键字段的名称。
  3. 指定主键的生成方式
    可以通过@TableId注解中的type属性指定主键的生成策略,具体支持哪些策略可以在IdType枚举中查看。

3、使用

@TableName(value ="user")
@Data
public class User implements Serializable {
/**
* 主键ID
*/
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long userId;
private String name;
private Integer age;
private String email;

三、主键生成策略-IdType枚举说明

通过查看IdType枚举类的源码,可以发现Mybatis-Plus中默认支持5种主键生成方式。

1、源码

public enum IdType {
AUTO(0),
NONE(1),
INPUT(2),
ASSIGN_ID(3),
ASSIGN_UUID(4);

private final int key;

private IdType(int key) {
this.key = key;
}

public int getKey() {
return this.key;
}
}

2、说明


描述

AUTO

数据库 ID自增,这种情况下将表中主键设置为自增,否则,没有设置主动设置id值进行插入时会报错

NONE

无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里默认 ASSIGN_ID),注意这里官网文档有误

INPUT

insert 前自行 set 主键值,在采用IKeyGenerator类型的ID生成器时必须为INPUT

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 方法)

3、全局设置

IdType默认的全局设置为​​IdType.ASSIGN_ID​​,即由mybatis-plus主动分配主键,默认情况下由默认主键生成器实现类DefaultIdentifierGenerator采用雪花算法填充主键。

public DbConfig() {
this.idType = IdType.ASSIGN_ID;
this.tableUnderline = true;
this.capitalMode = false;
this.logicDeleteValue = "1";
this.logicNotDeleteValue = "0";
this.insertStrategy = FieldStrategy.NOT_NULL;
this.updateStrategy = FieldStrategy.NOT_NULL;
this.whereStrategy = FieldStrategy.NOT_NULL;
}

在spring boot中,可以通过如下配置更改全局配置。

mybatis-plus.global-config.db-config.id-type=assign_id

三、ID生成器介绍

Mybatis-Plus中的ID生成器主要分为2类,一类是​​IdentifierGenerator​​​,另一类是​​IKeyGenerator​​。

Mybatis-Plus主键生成策略详解_id_02

1、IdentifierGenerator

源码如下:

public interface IdentifierGenerator {
//根据id是否为null判断是否需要主动分配Id
default boolean assignId(Object idValue) {
return StringUtils.checkValNull(idValue);
}

//生成数值型Id
Number nextId(Object entity);

//生成字符型uuid
default String nextUUID(Object entity) {
return IdWorker.get32UUID();
}
}

说明:
IdentifierGenerator生成器中主要提供了3个方法。
其使用场景是:​​​不依赖数据库生成ID,而是由mybatis-plus自己提供一套id生成算法。 对应的主键生成方式为IdType.ASSIGN_ID、ASSIGN_UUID​​。

  • ​assignId​​ 是否需要分配id
  • ​nextId​​ 获取下一个数值型Id
  • ​nextUUID​​ 获取下一个uuid

典型的实现是默认的id生成器DefaultIdentifierGenerator,基于雪花算法生成id。`

public class DefaultIdentifierGenerator implements IdentifierGenerator {
private final Sequence sequence;

public DefaultIdentifierGenerator() {
this.sequence = new Sequence((InetAddress)null);
}

public DefaultIdentifierGenerator(InetAddress inetAddress) {
this.sequence = new Sequence(inetAddress);
}

public DefaultIdentifierGenerator(long workerId, long dataCenterId) {
this.sequence = new Sequence(workerId, dataCenterId);
}

public DefaultIdentifierGenerator(Sequence sequence) {
this.sequence = sequence;
}

public Long nextId(Object entity) {
return this.sequence.nextId();
}
}

具体使用:
1、声明由mybatis-plus分配主键值

@TableName(value ="user")
@Data
public class User implements Serializable {
/**
* 主键ID
*/
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long userId;
private String name;
private Integer age;
private String email;

2、指定idGenerator的实现类
如果是默认的DefaultIdentifierGenerator,则不需要用户重新指定。

@Configuration
public class IdAutoConfig {
@Value("${mybatis-plus.zookeeper.serverLists}")
private String zkServerLists;

@Bean
public IdentifierGenerator idGenerator() {
return new ImadcnIdentifierGenerator(zkServerLists);
}
}

2、IKeyGenerator

源码如下:

public interface IKeyGenerator {
//执行sql生成id
String executeSql(String incrementerName);

//获取数据库类型
DbType dbType();
}

说明:
​​​IKeyGenerator​​​ 生成器主要是根据不同的数据库类型,​​执行sql语句生成对应的主键​​。典型的数据库如Oracle,Postgre,需要根据序列器生成表主键。

相关实现类:

Mybatis-Plus主键生成策略详解_数据库_03


OracleKeyGenerator中的实现:

可以发现,是通过执行sql调用序列器生成的id。

public class OracleKeyGenerator implements IKeyGenerator {
public OracleKeyGenerator() {
}

public String executeSql(String incrementerName) {
return "SELECT " + incrementerName + ".NEXTVAL FROM DUAL";
}

public DbType dbType() {
return DbType.ORACLE;
}
}

具体使用:
1、在实体中通过​​​@KeySequence​​​指定序列器名称,并通过@TableId指定主键生成策略为​​IdType.INPUT​

@KeySequence(value = "SEQ_ORACLE_STRING_KEY", clazz = String.class)
public class YourEntity {

@TableId(value = "ID_STR", type = IdType.INPUT)
private String idStr;

}

2、spring boot配置列中配置keyGenerator具体实现类

@Bean
public IKeyGenerator keyGenerator() {
return new OracleKeyGenerator();
}

也可以通过配置项指定:

mybatis-plus.global-config.db-config.key-generators=com.baomidou.mybatisplus.extension.incrementer.OracleKeyGenerator

四、自定义主键生成器

自定义主键生成器也有2种方式。
​​​如果需要通过执行sql语句来生成id的,可以通过实现IKeyGenerator接口来自定义。 如果不想依赖数据库,完全自定义一套主键生成策略,那么可以通过实现IdentifierGenerator接口来扩展。​

下面演示如何通过实现IdentifierGenerator接口,自定义主键生成器。

1、自定义id生成器

@Component
public class CustomIdGenerator implements IdentifierGenerator {
@Override
public Long nextId(Object entity) {
//可以将当前传入的class全类名来作为bizKey,或者提取参数来生成bizKey进行分布式Id调用生成.
String bizKey = entity.getClass().getName();
//根据bizKey调用分布式ID生成
long id = ....;
//返回生成的id值即可.
return id;
}
}

2、配置类中指定id生成器

@Bean
public IdentifierGenerator idGenerator() {
return new CustomIdGenerator();
}

3、实体类中指定主键分配策略​​IdType.ASSIGN_ID​

@TableName(value ="user")
@Data
public class User implements Serializable {
/**
* 主键ID
*/
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long userId;
private String name;
private Integer age;
private String email;

总结

本文主要是介绍了Mybatis-Plus主键生成策略及其相关的扩展方法。

1、详细介绍了@TableId注解的属性和作用,推荐项目中在实体的主键字段上明确添加@TableId注解,标识id字段以及id生成策略IdType。

2、目前mybatis-plus中有5种Id生成策略IdType,搞清楚各种的用法和使用场景。

  • ​AUTO​​ 数据库 ID自增
  • ​NONE​​ 未设置主键类型,也就是跟随全局策略,全局策略默认为ASSIGN_ID
  • ​INPUT​​ insert 前自行 set 主键值
  • ​ASSIGN_ID​​ 分配 ID
  • ​ASSIGN_UUID​​ 分配 UUID

3、Mybatis-Plus中的ID生成器主要分为2类,一类是​​IdentifierGenerator​​​,另一类是​​IKeyGenerator​​,搞清楚他们的区别和各自的使用场景。

  • ​IdentifierGenerator​​ 适用于不依赖数据库,用户自定义的主键生成场景。
  • ​IKeyGenerator​​ 依赖数据库,通过执行sql语句生成主键的场景。


标签:IdType,生成器,主键,public,Plus,Mybatis,ID,id
From: https://blog.51cto.com/u_15905482/5919952

相关文章

  • Mybatis
    1.什么是Mybatis?MyBatis是一个可以自定义SQL、存储过程和高级映射的持久层框架。Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本......
  • MySQL主键自增
    1.查看自增值SELECTAuto_incrementFROMinformation_schema.TABLESWHERETable_Schema='database'ANDtable_name='tableName'2.设置自增值altertable......
  • mybatis plus中使用joda-time
    支持JodaDateTime例如Pojo/Mopackagecom.xxx.crud.eo;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableFi......
  • mybatis一级缓存和二级缓存使用详解
    文章目录​​一、概念说明​​​​1、一级缓存​​​​2、二级缓存​​​​3、比较​​​​二、mybatis缓存的生命周期​​​​三、一级缓存的使用​​​​四、二级缓存的使......
  • mybatis-plus雪花算法生成Id使用详解
    文章目录​​前言​​​​一、mybatis-plus官网​​​​二、雪花算法实战​​​​1.建表​​​​2.新建测试工程​​​​3.单元测试​​​​三、实现分析​​​​四、为什么......
  • Mybatis-Plus字段策略FieldStrategy详解
    文章目录​​前言​​​​一、官方文档​​​​二、字段策略介绍​​​​1、FieldStrategy作用​​​​2、FieldStrategy类型​​​​3、FieldStrategy配置​​​​全局策略......
  • Mybatis-Plus通过SQL注入器实现真正的批量插入
    文章目录​​前言​​​​一、mysql批量插入的支持​​​​二、Mybatis-Plus默认saveBatch方法解析​​​​1、测试工程建立​​​​2、默认批量插入saveBatch方法测试​​......
  • mybatis-plus雪花算法增强:idworker
    文章目录​​前言​​​​一、官网​​​​二、默认实现的弊端​​​​三、mybatis-plus中datacenterId和workerId的默认生成规则​​​​四、idworker介绍​​​​五、idwo......
  • Mybatis-Plus中updateById方法不能更新空值问题
    问题描述在Mybatis-Plus中调用updateById方法进行数据更新默认情况下是不能更新空值字段的。而在实际开发过程中,往往会遇到需要将字段值更新为空值的情况。那么如果让Mybat......
  • mybatis-plus异常记录:org.apache.ibatis.binding.BindingException Invalid bound st
    问题描述我们在使用mybatis或mybatis-plus作为持久化框架的时候,通过dao层接口调用xml中配置好的sql时,常常会遇到​​org.apache.ibatis.binding.BindingExceptionInvalidb......