背景介绍
在使用 MyBatis-Plus 框架时,主键生成是一个常见的需求。MyBatis-Plus 提供了多种主键生成策略,其中包括数据库自增、UUID 和雪花算法。雪花算法因其在高并发场景下的高效性和唯一性而被广泛采用。然而,有时候开发者会遇到使用雪花算法生成的主键值异常大,甚至为负数的问题。
问题描述
在使用 MyBatis-Plus 时,如果主键生成策略设置为雪花算法,可能会遇到以下问题:
- 新增记录时,生成的主键值异常大。
- 有时候生成的主键值为负数。
这些问题会导致数据库主键冲突,影响系统的稳定性和数据的一致性。
原因分析
1. 代码未设置 @TableId
注解
在实体类中,如果主键字段没有正确设置 @TableId
注解,MyBatis-Plus 将无法正确识别主键生成策略,从而导致生成的主键值异常。
2. 字段类型设置不当
如果主键字段的类型设置为 Integer
或数据库字段类型设置为 INT
,而主键生成策略设置为雪花算法,可能会导致生成的主键值超出 Integer
或 INT
的范围,从而生成负数。
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 时生成的主键值异常大或为负数的问题。