使用Mybatis-plus出现数据库id很大或者为负数情况排查解决

背景介绍

在使用 MyBatis-Plus 框架时,主键生成是一个常见的需求。MyBatis-Plus 提供了多种主键生成策略,其中包括数据库自增、UUID 和雪花算法。雪花算法因其在高并发场景下的高效性和唯一性而被广泛采用。然而,有时候开发者会遇到使用雪花算法生成的主键值异常大,甚至为负数的问题。

问题描述

在使用 MyBatis-Plus 时,如果主键生成策略设置为雪花算法,可能会遇到以下问题:

  • 新增记录时,生成的主键值异常大。
  • 有时候生成的主键值为负数。

这些问题会导致数据库主键冲突,影响系统的稳定性和数据的一致性。

原因分析

1. 代码未设置 @TableId 注解

在实体类中,如果主键字段没有正确设置 @TableId 注解,MyBatis-Plus 将无法正确识别主键生成策略,从而导致生成的主键值异常。

2. 字段类型设置不当

如果主键字段的类型设置为 Integer 或数据库字段类型设置为 INT,而主键生成策略设置为雪花算法,可能会导致生成的主键值超出 IntegerINT 的范围,从而生成负数。

3. 雪花算法参数配置不当

雪花算法生成的主键值由时间戳、机器标识和序列号组成。如果时间戳部分过大,或者机器标识和序列号部分配置不当,都会导致生成的主键值异常大。

4. 数据库表初始值设置不当

即使代码中正确设置了 @TableId 注解,如果数据库表的初始值设置不当,也会导致生成的主键值异常。例如,如果数据库表的 AUTO_INCREMENT 初始值设置得过大,后续插入的数据也会受到影响。

解决方案

1. 设置 @TableId 注解

确保在实体类中正确设置 @TableId 注解,并指定主键生成策略为雪花算法。例如:

java 复制代码
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;

public class User {
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    private String name;
    private String email;

    // getters and setters
}

2. 调整字段类型

确保主键字段的类型设置为 Long,并且数据库字段类型设置为 BIGINT,以避免生成的主键值超出范围。例如:

java 复制代码
public class User {
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    private String name;
    private String email;

    // getters and setters
}

数据库字段类型设置为 BIGINT

sql 复制代码
CREATE TABLE users (
    id BIGINT NOT NULL AUTO_INCREMENT,
    name VARCHAR(255),
    email VARCHAR(255),
    PRIMARY KEY (id)
);

3. 检查雪花算法参数配置

确保雪花算法的参数配置合理。MyBatis-Plus 默认的雪花算法配置通常是合理的,但如果需要自定义参数,可以参考以下配置:

yaml 复制代码
  global-config:
    dbConfig:
      # 主键类型
      # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
      idType: ASSIGN_ID

4. 调整数据库表初始值

如果数据库表的 AUTO_INCREMENT 初始值设置得过大,可以通过以下 SQL 语句将其调整为合理的值:

sql 复制代码
ALTER TABLE users AUTO_INCREMENT = 1;

5. 重启后台服务

在调整完代码和数据库配置后,重启后台服务以确保所有更改生效。

示例代码

实体类

java 复制代码
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;

public class User {
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    private String name;
    private String email;

    // getters and setters
}

映射文件

xml 复制代码
<mapper namespace="com.example.mapper.UserMapper">
    <insert id="insertUser">
        INSERT INTO users (name, email)
        VALUES (#{name}, #{email})
    </insert>
</mapper>

数据库配置

yaml 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydatabase
    username: root
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver

  global-config:
    dbConfig:
      # 主键类型
      # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
      idType: ASSIGN_ID

结论

通过正确设置 @TableId 注解、调整字段类型、检查雪花算法参数配置、调整数据库表初始值,并重启后台服务,可以有效解决使用 MyBatis-Plus 时生成的主键值异常大或为负数的问题。

相关推荐
m0_7482338814 分钟前
Spring Boot 集成 MyBatis 全面讲解
spring boot·后端·mybatis
行十万里人生26 分钟前
Qt 对象树详解:从原理到运用
开发语言·数据库·qt·华为od·华为·华为云·harmonyos
松岛的枫叶34 分钟前
【缓冲区】数据库备份的衍生问题,缓冲区在哪里?JVMor操作系统?(二)
数据库
littlegirll1 小时前
命令行方式安装KFS同步KES到KADB
java·大数据·数据库
Y编程小白2 小时前
MySQL的存储引擎
数据库·mysql
爱老的虎油2 小时前
MySQL零基础教程10—正则表达式搜索(下)
数据库·mysql·正则表达式
️Carrie️2 小时前
6.6.3 SQL数据查询(一)
数据库·sql·select·子查询·连接查询·简单查询·聚集函数
jay丿2 小时前
Django应用的高级配置和管理
数据库·django·sqlite
虎鲸不是鱼3 小时前
【全栈开发】从0开始搭建一个图书管理系统【一】框架搭建
java·spring boot·spring·maven·mybatis
ILUUSION_S3 小时前
学习路程五 向量数据库Milvus操作
数据库·python·学习·langchain·milvus