Mybatisplus自定义主键生成策略,使用雪花算法生成16位的唯一ID

发布时间 2023-12-06 16:59:44作者: 彧未

楼主在使用mybatisplus开发前后端分离项目时发现一个很奇怪的现象:所有更新/删除操作都不起作用,开启mybatis日志后发现前端传入的id值与实际的数据库的值不相同,最后三位总是000。

经过一系列查资料才知道,mybatisplus的默认ID生成器使用雪花算法,生成20位左右的ID,但json数据传到前端会丢失精度,基本只有17位,剩下的就用0来补充了。

解决方法有两种:第一种是将ID在传入传出时修改类型为String,这样就不会丢失精度,第二种方法是自定义ID生成器,这样就可以生成17位以内的ID了,楼主采用的是第二种方法如下:

 

mybatisplus官网传送门:https://baomidou.com/pages/568eb2/#spring-boot

 

第一步:在pom.xml中引入hutool依赖

1 <dependency>
2     <groupId>cn.hutool</groupId>
3     <artifactId>hutool-core</artifactId>
4     <version>5.3.8</version>
5 </dependency>

第二步:在springboot的配置文件中增加mybatisplus的配置

 1 mybatis-plus:
 2   configuration:
 3     # 开启驼峰转换
 4     map-underscore-to-camel-case: true
 5     # 打印日志到控制台
 6     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 7   global-config:
 8     db-config:
 9       # 这是默认的雪花算法生成主键
10       id-type: assign_id

第二步:新建Bean(楼主采用在MybatisplusConf中新加函数@Bean)

 1 @Configuration
 2 public class MybatisPlusConf {
 3     /**
 4      * 自定义MP的主键生成策略
 5      */
 6     @Bean
 7     public IdentifierGenerator idGenerator() {
 8         return new MyIdGenerator();
 9     }
10 }

第三步:编写自己的ID生成器MyIdGenerator(主要是重写nextId这个方法)

 1 import cn.hutool.core.lang.Snowflake;
 2 import cn.hutool.core.util.IdUtil;
 3 import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
 4 
 5 /**
 6  * MP的ID生成器
 7  */
 8 public class MyIdGenerator implements IdentifierGenerator {
 9     private static final Snowflake snowflake = IdUtil.createSnowflake(1, 1);
10 
11     @Override
12     public boolean assignId(Object idValue) {
13         return IdentifierGenerator.super.assignId(idValue);
14     }
15 
16     @Override
17     public String nextUUID(Object entity) {
18         return IdentifierGenerator.super.nextUUID(entity);
19     }
20 
21     /**
22      * 截取雪花算法的后16位作为ID
23      */
24     @Override
25     public Number nextId(Object entity) {
26         long id = snowflake.nextId();
27         // 将生成的 ID 转换为 16 位数字,然后再转换为 Long 类型
28         String idStr = String.valueOf(id);
29         if (idStr.length() < 16) {
30             idStr = "0".repeat(16 - idStr.length()) + idStr;
31         } else if (idStr.length() > 16) {
32             idStr = idStr.substring(idStr.length() - 16);
33         }
34         return Long.parseLong(idStr);
35     }
36 }

这样就大功告成了