mybatis-plus雪花算法生成Id使用详解

简介: mybatis-plus雪花算法生成Id使用详解

前言


在实际开发过程中,数据库自增主键生成Id能满足大部分的场景。

但是随着分布式应用场景的增多,表数据的增大导致分表分库的大量应用。

数据库自增主键的生成规则无法满足对应的业务场景,于是诞生了越来越多的分布式ID生成算法,其中雪花算法是目前最为流行的。

今天说一下在mybatis-plus中如何使用雪花算法生成Id。


一、mybatis-plus官网


官方文档:https://baomidou.com/


Git地址:https://github.com/baomidou/mybatis-plus


TIP⚠️:

推荐学习框架的使用的时候,都多研究下官网,获取第一手资料。


二、雪花算法实战


1.建表

DROP TABLE IF EXISTS user;
CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);


注意⚠️:

这里的主键字段没有配置自增生成策略,所以执行新增操作的时候,需要给id字段设置值,才能新增成功。类似如下:


INSERT INTO user ( id, name, age, email ) VALUES ( 123434, 'test', 13, '101@qq.com')


2.新建测试工程

6.png

相关代码:

maven依赖:


<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


实体User:

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}


mapper:
public interface UserMapper extends BaseMapper<User> {
}


启动类Application:

@SpringBootApplication
@Slf4j
@MapperScan("com.laowan.mybatis_plus.mapper")
public class MybatisPlusApplication {
    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class, args);
        log.info("mybatis_plus_demo 启动成功");
    }
}


注意⚠️:

这里在启动类上配置了@MapperScan(“mapper接口目录”),所以在UserMapper接口上没有添加@Mapper注解。


@Mapper配置方法:

@Mapper
public interface UserMapper extends BaseMapper<User> {
}


两者任意选择一种方式配置即可,如果都不配置,那么在执行dao层方法进行数据操作时,会出现在spring容器中找不到对应的bean的异常。


@Mapper和@MapperScan都不配置调用mapper方法时出现的异常:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.laowan.mybatis_plus.mapper.UserMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

配置属性:

server.port=8080
logging.level.com.laowan.mybatis_plus.mapper=debug
spring.datasource.url = jdbc:mysql://localst:3306/seckill?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
spring.datasource.username = root
spring.datasource.password = 123456


3.单元测试

@SpringBootTest
class MybatisPlusApplicationTests {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void testInsert() {
        System.out.println(("----- insert method test ------"));
        User user = new User();
        user.setName("test");
        user.setAge(13);
        user.setEmail("101@qq.com");
        userMapper.insert(user);
        System.out.println(user.toString());
    }


执行结果:

5.png

User(id=728666272023183375, name=test, age=13, email=101@qq.com)


多次执行,发现主键ID的确呈趋势递增,并且符合雪花算法的规范。

4.png

结论:

主键id的生成策略已经采用了雪花算法,呈趋势递增。


三、实现分析


很多人可能疑惑🤔,你这明明啥都没干,怎么就实现了雪花算法生成Id。

其实mybatis-plus已经内置雪花算法生成分布式唯一id。

在mybatis-plus特性中已经明确说明了这点。

3.png

我们可以直接在IDEA中双击shift搜索Sequence类查看其具体实现,可以发现其实现就是采用了雪花算法。

2.png


四、为什么默认就是雪花算法


实体User:

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}


这里可以看到我们并没有在实体类的id上设置id生成策略。

其实mybatis-plus中默认的主键生成策略为DefaultIdentifierGenerator,里面的实现就是采用Sequence生成主键。

1.png

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();
    }
}


五、主动设置Id生成策略


可以通过mybatis-plus中的@TableId主键,主动标识主键字段,并配置主键生成策略。


@Data
public class User {
    //采用IdentifierGenerator默认的实现类DefaultIdentifierGenerator生成id
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}


121.png


六、内置的雪花算法工具类:IdWorker


在mybatis-plus中,已经内置了雪花算法的工具类IdWorker,其实现原理也是通过默认的ID生成器DefaultIdentifierGenerator来实现。


如果项目开发中需要主动去获取雪花id通过编码实现业务逻辑,可以使用其中的相关方法。

1120.png

public static void main(String[] args) {
    // 返回值  1385106677482582018
    System.out.println(IdWorker.getId());
    // 返回值 "1385106677482582019"
    System.out.println(IdWorker.getIdStr());
}


注意⚠️:

在github中有一个很流行的分布式统一ID生成框架也叫idworker,需要和mybatis-plus中自带的Idworker工具类区分开来。


idworker 是一个基于zookeeper和snowflake算法的分布式统一ID生成工具,通过zookeeper自动注册机器(最多1024台),无需手动指定workerId和dataCenterId。


idworker官网:https://github.com/imadcn/idworker


mybatis-plus雪花算法增强idworker:https://laowan.blog.csdn.net/article/details/125607205


总结


mybatis-plus已经内置了雪花算法生成分布式唯一Id,并且是默认的ID生成策略。

大家在实际项目中,可以通过在主键字段上添加@TableId注解来控制主键的生成策略。

目录
相关文章
|
4月前
|
算法 Go
[go 面试] 雪花算法与分布式ID生成
[go 面试] 雪花算法与分布式ID生成
|
24天前
|
算法 关系型数据库 MySQL
分布式唯一ID生成:深入理解Snowflake算法在Go中的实现
在分布式系统中,确保每个节点生成的 ID 唯一且高效至关重要。Snowflake 算法由 Twitter 开发,通过 64 位 long 型数字生成全局唯一 ID,包括 1 位标识位、41 位时间戳、10 位机器 ID 和 12 位序列号。该算法具备全局唯一性、递增性、高可用性和高性能,适用于高并发场景,如电商促销时的大量订单生成。本文介绍了使用 Go 语言的 `bwmarrin/snowflake` 和 `sony/sonyflake` 库实现 Snowflake 算法的方法。
32 1
分布式唯一ID生成:深入理解Snowflake算法在Go中的实现
|
4月前
|
SQL 算法 Serverless
B端算法实践问题之使用concat_id算子获取用户最近点击的50个商品ID如何解决
B端算法实践问题之使用concat_id算子获取用户最近点击的50个商品ID如何解决
29 1
|
4月前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
114 0
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
5月前
|
算法 数据库
MybatisPlus-标准CRUD制作,新增boolean save(T t),删除 ~ delete(int id),修改 ~ update(T t),根据id查询,T getById....
MybatisPlus-标准CRUD制作,新增boolean save(T t),删除 ~ delete(int id),修改 ~ update(T t),根据id查询,T getById....
|
5月前
|
文字识别 算法 Java
文本,保存图片09,一个可以用id作为图片名字的pom插件,利用雪花算法生成唯一的id
文本,保存图片09,一个可以用id作为图片名字的pom插件,利用雪花算法生成唯一的id
|
6月前
|
算法 数据中心 Python
基于python雪花算法工具类Snowflake-来自chatGPT
基于python雪花算法工具类Snowflake-来自chatGPT
130 4
|
6月前
|
算法 PHP 数据中心
基于php雪花算法工具类Snowflake -来自chatGPT
基于php雪花算法工具类Snowflake -来自chatGPT
115 2
|
6月前
|
算法 数据中心 C++
基于C++雪花算法工具类Snowflake -来自chatGPT
基于C++雪花算法工具类Snowflake -来自chatGPT