源本科技 | 码上会

自定义 ID 生成器

2026/04/03
2
0

引言

MyBatis-Plus 提供了灵活的自定义 ID 生成器功能,允许开发者根据业务需求定制主键 ID 生成策略。自 3.3.0 版本起,框架默认采用雪花算法 + 无中划线 UUID 作为主键 ID 生成方式,兼顾分布式场景下的 ID 唯一性、有序性与性能。


自带主键生成策略

MyBatis-Plus 内置了两种通用主键生成策略,通过 IdType 枚举指定,适配不同主键类型场景:

方法

主键生成策略

支持主键类型

说明

nextId

ASSIGN_ID

Long, Integer, String

基于雪花算法生成分布式 ID;支持自动转换为 String 类型,数值类型需精准匹配(如返回 Long,实体主键不可定义为 Integer)

nextUUID

ASSIGN_UUID

String

生成默认不含中划线的 UUID 字符串,全局唯一但无序


IdentifierGenerator

自定义 ID 生成器的核心前提:实现 MyBatis-Plus 提供的 com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator 接口。 该接口定义了主键生成的标准规范,包含 2 个核心方法:

public interface IdentifierGenerator {
    // 生成数值型主键 ID(Long/Integer)
    Number nextId(Object entity);
    // 生成字符串型主键 ID(UUID/自定义字符串)
    default String nextUUID(Object entity) {
        return IdWorker.get32UUID();
    }
}
  • 默认实现类:DefaultIdentifierGenerator(雪花算法 + UUID 实现)

  • 自定义生成器必须重写 nextId 方法(数值型 ID)或 nextUUID 方法(字符串型 ID)


自定义 ID 生成器

前置必备配置

实体类主键必须通过 @TableId 注解指定生成策略,否则自定义生成器不生效:

// 数值型 ID 用 ASSIGN_ID
@TableId(type = IdType.ASSIGN_ID)
private Long id;

// 字符串型 ID 用 ASSIGN_UUID
@TableId(type = IdType.ASSIGN_UUID)
private String id;

Spring Boot 环境下,通过 3 种方式将自定义生成器注册为 Spring Bean,MP 会自动扫描注入。

步骤 1

编写自定义 ID 生成器

import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import org.springframework.stereotype.Component;

/**
 * 自定义 ID 生成器
 */
@Component
public class CustomIdGenerator implements IdentifierGenerator {

    /**
     * 重写数值型 ID 生成方法
     * @param entity 当前插入的实体对象(可获取类名、字段值等业务参数)
     * @return 生成的分布式 ID
     */
    @Override
    public Long nextId(Object entity) {
        // 示例1:获取实体类名作为业务键(区分不同表的 ID 生成)
        String bizKey = entity.getClass().getName();
        // 示例2:基于雪花算法自定义生成 ID(也可调用分布式 ID 服务,如 Leaf/Snowflake)
        long id = com.baomidou.mybatisplus.core.toolkit.IdWorker.getId();
        // 可根据业务需求加密、拼接、格式化 ID
        return id;
    }

    /**
     * 可选:重写字符串型 UUID 生成方法
     */
    @Override
    public String nextUUID(Object entity) {
        // 自定义无符号/带前缀的 UUID
        return "biz_" + java.util.UUID.randomUUID().toString().replace("-", "");
    }
}

步骤 2

3 种注册方式

方式 1

直接声明为 Bean(最简)

在生成器类上添加 @Component 注解(如上代码),Spring 自动扫描注入。

方式 2

配置类手动注册

import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

方式 3

通过 MybatisPlusPropertiesCustomizer 自定义

import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusPropertiesCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusPropertiesCustomizer plusPropertiesCustomizer() {
        return plusProperties -> {
            GlobalConfig globalConfig = plusProperties.getGlobalConfig();
            globalConfig.setIdentifierGenerator(new CustomIdGenerator());
        };
    }
}

最佳实践

  1. 类型严格匹配 nextId 返回 Long 时,实体主键必须定义为 Long;返回 String 时,主键需定义为 String

  2. 分布式场景 自定义生成器需保证全局唯一,推荐基于雪花算法、百度 Leaf、美团 Leaf 等分布式 ID 方案实现。

  3. 注解必配 实体类必须添加 @TableId(type = IdType.ASSIGN_ID/ASSIGN_UUID),否则 MP 不会调用自定义生成器。

  4. 性能优化 避免在 nextId 方法中编写耗时逻辑(如数据库查询),保证 ID 生成的高性能。


总结

  1. 自定义 ID 生成器核心是实现 IdentifierGenerator 接口,重写 nextId/nextUUID 方法;

  2. Spring Boot 环境用 @Component 最简注册,必须配合 @TableId 注解生效;

  3. MP 的 IdentifierGenerator 专注主键生成,是 MyBatis-Plus 项目的首选方案;

  4. 自 3.3.0 版本起,MP 默认使用雪花算法 + 无中划线 UUID 生成主键。