MyBatis-Plus主键回填详解:插入数据后自动获取主键值
MyBatis-Plus主键回填详解:插入数据后自动获取主键值
本文深度剖析MyBatis-Plus主键回填机制,解决插入数据后无法获取主键ID的痛点问题!
一、什么是主键回填?
主键回填(Key Retrieval) 指的是在数据库插入操作后,自动将生成的主键值回填到实体对象中的技术。在以下场景中尤为重要:
- 插入数据后需要立即使用该主键进行关联操作
- 需要将生成的主键返回给前端使用
- 在日志记录中需要包含该主键信息
二、常见的数据库主键生成策略
策略类型 | 实现方式 | 适用数据库 |
---|---|---|
自增主键 | AUTO_INCREMENT | MySQL, SQL Server |
序列 | SEQUENCE | Oracle, PostgreSQL |
UUID | 应用层生成 | 所有数据库 |
分布式ID | Snowflake等算法 | 所有数据库 |
三、MyBatis-Plus主键回填实现方式
方式1:注解配置(推荐)
在实体类的主键字段添加@TableId
注解:
@Data
public class User {// 使用数据库自增主键并开启回填@TableId(type = IdType.AUTO)private Long id;private String name;private Integer age;
}
方式2:全局配置(yml文件)
mybatis-plus:global-config:db-config:id-type: auto # 全局主键策略select-strategy: not_empty
支持的ID生成策略(IdType枚举)
策略 | 说明 |
---|---|
AUTO | 数据库ID自增(需数据库支持) |
NONE | 无状态,需手动设置 |
INPUT | 用户输入ID |
ASSIGN_ID | 分配ID(默认雪花算法) |
ASSIGN_UUID | 分配UUID |
ID_WORKER | 已弃用,等同于ASSIGN_ID |
四、完整代码示例
实体类定义
@Data
@TableName("sys_user")
public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private Integer age;
}
Service层实现
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {@Overridepublic Long addUser(User user) {// 插入操作(会自动回填主键)baseMapper.insert(user);// 直接获取回填的主键值return user.getId(); }
}
测试用例
@SpringBootTest
class UserServiceTest {@Autowiredprivate UserService userService;@Testvoid testKeyBackfill() {User user = new User();user.setName("张三");user.setAge(25);// 插入前ID为nullassertNull(user.getId()); Long id = userService.addUser(user);// 验证主键回填assertNotNull(id);System.out.println("生成的主键ID: " + id);// 对象中的ID也被填充assertEquals(id, user.getId()); }
}
五、不同数据库的适配方案
1. MySQL(自增主键)
CREATE TABLE `sys_user` (`id` BIGINT NOT NULL AUTO_INCREMENT,`name` VARCHAR(50),PRIMARY KEY (`id`)
)
2. PostgreSQL(序列)
@TableId(type = IdType.INPUT)
@KeySequence(value = "seq_user", clazz = Long.class)
private Long id;
3. Oracle(序列同PostgreSQL)
CREATE SEQUENCE seq_user START WITH 1 INCREMENT BY 1;
六、踩坑记录与最佳实践
常见问题排查
-
回填值为null
- 检查数据库表主键是否设置为自增
- 确认数据库驱动支持主键回填(如MySQL需要JDBC 4.2+)
- 检查是否配置了
@TableId(type = IdType.AUTO)
-
批量插入回填失败
// 错误做法:批量插入不会回填ID List<User> users = ...; saveBatch(users); // 正确做法:使用专用方法 boolean success = saveOrUpdateBatch(users, 1000);
性能优化建议
- 避免在循环中单条插入,使用
saveBatch()
批量操作 - 分布式环境推荐使用
ASSIGN_ID
(雪花算法) - 高并发场景禁用
selectKey
方式(影响性能)
七、原理剖析
MyBatis-Plus通过KeyGenerator
接口实现主键回填:
public interface KeyGenerator {// 执行前生成(如UUID)void processBefore(Executor executor, ...);// 执行后生成(如自增ID)void processAfter(Executor executor, ...);
}
执行流程:
八、总结
主键回填功能要点:
- 注解驱动:
@TableId(type = IdType.AUTO)
是最简配置 - 自动填充:插入后实体对象自动持有主键值
- 多库适配:支持MySQL/Oracle/PostgreSQL等主流数据库
- 批量支持:使用
saveBatch()
系列方法支持批量回填
掌握主键回填技术,能显著提升开发效率,避免手动查询带来的冗余代码和性能损耗。MyBatis-Plus通过优雅的封装,让这一过程变得零侵入、自动化,真正实现了开箱即用的便捷体验!
参考资料:
- MyBatis-Plus官方文档 - 主键策略
- JDBC规范 - 自动生成键
- MySQL 8.0参考手册 - AUTO_INCREMENT
推荐阅读:
- MyBatis-Plus的10个高级特性
- 分布式ID生成方案对比