基本介绍
主键的作用是唯一标识,我们可以通过这个唯一标识来定位到这条数据。在数据库表数据中,主键的生成可以遵循自定义的规则,但手动生成通常比较繁琐。因此,在实际开发中,我们更倾向于使用框架提供的主键生成策略来自动生成主键。
在MybatisPlus中,提供了@TableId
注解来指定主键生成策略。这个注解允许我们为新增的数据指定主键生成方式。
@TableId 注解属性
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | "" | 主键字段名 |
type | Enum | 否 | IdType.NONE | 指定主键类型 |
type 类型枚举
AUTO
:数据库ID自增。该策略跟随数据库表的主键递增策略,前提是数据库表的主键要设置为自增。NONE
:无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于INPUT)。INPUT
:insert前自行set主键值。如果未设置主键值,则无法添加数据。ASSIGN_ID
:分配ID(主键类型为Number(Long和Integer)或String)。使用接口IdentifierGenerator
的方法nextId
(默认实现类为DefaultIdentifierGenerator
,采用雪花算法)。ASSIGN_UUID
:分配UUID,主键类型为String。使用接口IdentifierGenerator
的方法nextUUID
(默认实现为默认方法)。ID_WORKER
:分布式全局唯一ID长整型类型(建议使用ASSIGN_ID)。UUID
:32位UUID字符串(建议使用ASSIGN_UUID)。ID_WORKER_STR
:分布式全局唯一ID字符串类型(建议使用ASSIGN_ID)。
AUTO策略示例
当使用AUTO策略时,你需要确保数据库表的主键字段是自增的。
代码语言:java复制@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
}
// 测试方法
@Test
void testAutoPrimaryKey() {
User user = new User();
user.setName("Mary");
user.setAge(35);
user.setEmail("test7@powernode.com");
userMapper.insert(user); // 插入后,id字段会被自动赋值
}
INPUT策略示例
使用INPUT策略时,你需要在插入数据前手动设置主键值。
代码语言:java复制@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_user")
public class User {
@TableId(type = IdType.INPUT)
private Long id;
private String name;
private Integer age;
private String email;
}
// 测试方法
@Test
void testInputPrimaryKey() {
User user = new User();
user.setId(1L); // 必须手动设置id
user.setName("Jerry");
user.setAge(38);
user.setEmail("test8@powernode.com");
userMapper.insert(user); // 插入成功,因为id已设置
}
ASSIGN_ID策略示例
ASSIGN_ID策略使用雪花算法生成ID,适用于分布式环境。
代码语言:java复制@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_user")
public class User {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
// ... 其他字段
}
// 测试方法(与AUTO策略类似,但ID由框架自动生成)
@Test
void testAssignIdPrimaryKey() {
User user = new User();
user.setName("John");
user.setAge(28);
user.setEmail("test9@powernode.com");
userMapper.insert(user); // 插入后,id字段会被自动赋值(雪花算法生成)
}
ASSIGN_UUID策略示例
ASSIGN_UUID策略使用UUID算法生成主键,适用于需要全局唯一字符串ID的场景。
代码语言:java复制@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_user")
public class User {
@TableId(type = IdType.ASSIGN_UUID)
private String id; // 注意这里id的类型是String,以容纳UUID
private String name;
private Integer age;
private String email;
}
// 测试方法
@Test
void testAssignUuidPrimaryKey() {
User user = new User();
user.setName("Alice");
user.setAge(25);
user.setEmail("testA@powernode.com");
userMapper.insert(user); // 插入后,id字段会被自动赋值(UUID生成)
// 验证生成的UUID
String uuid = user.getId();
// 这里可以对uuid进行断言或者输出等操作
System.out.println("Generated UUID: " uuid);
}
ID_WORKER 和 ID_WORKER_STR 策略(已废弃)
请注意,ID_WORKER 和 ID_WORKER_STR 策略在Mybatis-Plus的较新版本中已经被废弃,建议使用 ASSIGN_ID 替代。ID_WORKER 和 ID_WORKER_STR 原本是基于Twitter的Snowflake算法实现的分布式唯一ID生成策略,但现在建议使用ASSIGN_ID,因为它提供了更灵活和可配置的ID生成方式。
自定义主键生成策略
如果你需要实现自定义的主键生成策略,可以实现 com.baomidou.mybatisplus.extension.incrementer.IdentifierGenerator
接口,并覆盖 nextId
或 nextUUID
方法。然后,你可以通过 @TableId
注解的 generator
属性指定你的自定义实现类。
// 自定义主键生成器
public class CustomIdGenerator implements IdentifierGenerator {
@Override
public Long nextId(Object entity) {
// 这里实现你的自定义ID生成逻辑
// ...
return yourCustomGeneratedId; // 返回你的自定义ID
}
@Override
public String nextUUID(Object entity) {
// 这里通常不会重写此方法,因为ASSIGN_UUID类型会使用默认的UUID生成策略
// ...
return null;
}
}
// 在实体类中使用自定义主键生成器
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_user")
public class User {
@TableId(type = IdType.ASSIGN_ID, generator = "customIdGenerator")
private Long id;
// ... 其他字段
// 还需要在Mybatis-Plus的配置中注册你的自定义主键生成器
// 例如,在Spring Boot应用中,你可以在MybatisPlusConfig类中注册
}
// MybatisPlusConfig配置类示例(Spring Boot)
@Configuration
public class MybatisPlusConfig {
@Bean
public IdentifierGenerator customIdGenerator() {
return new CustomIdGenerator();
}
// ... 其他Mybatis-Plus配置
}