SpringBoot+MyBatis插入后返回主键ID不正确的原因与解决办法
时间:2026-08-20 | 作者:电竞小硕 | 阅读:0前言
在使用MyBatis进行数据插入时,经常会遇到一个困惑:明明数据库里插入了数据,自动生成的主键id也正确,但代码里返回的int值却是1(或者一串负数),而不是期望的id值。今天就来彻底梳理一下这个问题的根源和正确做法。
先看一个典型场景:用注解@Options(useGeneratedKeys = true, keyProperty = "id")配置了自动回填主键,但执行完插入后,返回的int id始终是1,检查数据库,数据确实插入成功,id也正确。这到底是怎么回事?
下面分别用注解开发和XML映射两种方式演示,并给出正确的取值方式。
业务代码片段(错误示范):
Integer id = tblSchoolOrganizationInfoMapper.insertReturnId(info);
id = info.getId();
log.info("插入成功!id = {}", id);
注解开发代码:
@Mapper public interface TblSchoolOrganizationInfoMapper extends BaseMapper{ @Insert("INSERT INTO TblSchoolOrganizationInfo(`createTime`, `isDeleted`, `updateTime`, `code`, `name`, `remarks`, `theOrder`, `childNum`, `isLeaf`, `parentId`, `theLevel`, `trainingScope`, `allNodesName`, `rootId`, `secondNodeId`, `account`) " + "VALUES(#{createtime},#{isdeleted},#{updatetime},#[code],#{name},#{remarks},#{theorder},#{childnum},#{isleaf},#{parentid},#{thelevel},#{trainingscope},#{allnodesname},#{rootid},#{secondnodeid},#{account})") @Options(useGeneratedKeys = true, keyProperty = "id") Integer insertReturnId(TblSchoolOrganizationInfo info); }
XML映射形式:
INSERT INTO TblSchoolOrganizationInfo (`createTime`, `isDeleted`, `updateTime`, `code`, `name`, `remarks`, `theOrder`, `childNum`, `isLeaf`, `parentId`, `theLevel`, `trainingScope`, `allNodesName`, `rootId`, `secondNodeId`, `account`) VALUES (#{createtime}, #{isdeleted}, #{updatetime}, #[code], #{name}, #{remarks}, #{theorder}, #{childnum}, #{isleaf}, #{parentid}, #{thelevel}, #{trainingscope}, #{allnodesname}, #{rootid}, #{secondnodeid}, #{account})
注意事项
1. 表的主键必须设置为自增(AUTO_INCREMENT),否则无法自动生成id。
2. 无论使用注解还是XML,都必须显式声明useGeneratedKeys=true和keyProperty。注解用@Options,XML用。如果缺少这个配置,虽然插入成功,但返回的id可能是一串很大的负数,比如-759160831。
3. 编写SQL时,不要在INSERT语句中手动为自增主键列赋值(即不写id字段),否则MyBatis无法正确回填主键,也可能导致id值异常。
4. 最容易踩的坑:插入方法的返回值并不是你期望的id,而是数据库受影响的行数(int)。所以直接接收返回值得到的永远是1(或0)。但MyBatis会自动将生成的主键值设置到传入的参数对象中(通过keyProperty指定的属性)。因此正确的做法是:忽略返回值,直接通过参数对象获取id。
实际应该是这样
Integer row = tblSchoolOrganizationInfoMapper.insertReturnId(info);
log.info("插入成功!影响的行数 row = {}", row);
Integer id = info.getId();
log.info("插入成功!id = {}", id);
其实原理很简单:MyBatis在执行插入后,通过JDBC的getGeneratedKeys方法获取数据库生成的主键,然后通过反射设置到传入对象的指定属性中。返回值只是执行影响的记录数,与主键无关。
总结
以上经验可以帮助快速定位类似问题:先确认表自增配置和useGeneratedKeys声明,然后记住操作对象而非返回值。只要正确配置,通过info.getId()就能拿到期望的id值。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- Java异常处理实战:从体系架构到健壮性设计全解
- 时间:2026-08-27
-
- 基于Spring Security实现自动登录的完整指南
- 时间:2026-08-27
-
- VS Code Java开发高效配置清单(可直接复制使用)
- 时间:2026-08-27
-
- JavaSwing实现自定义TablePanel组件(附完整代码)
- 时间:2026-08-27
-
- Java基础攻略:输入输出、方法与数组实战指南
- 时间:2026-08-27
-
- Java反射、枚举、Lambda表达式及泛型通配符实例详解
- 时间:2026-08-27
-
- 30个经典算法题及Java解答(含实例代码)
- 时间:2026-08-27
-
- Spring Data JPA 查询实战:方法命名与 @Query 注解详解
- 时间:2026-08-27
精选合集
更多大家都在玩
大家都在看
更多-
- 糖尿病完全不能吃糖吗
- 时间:2026-09-15
-
- 蚂蚁庄园小课堂2026年9月16日最新题目答案
- 时间:2026-09-15
-
- 小鸡答题今天的答案是什么2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园每日答题答案2026年9月16日
- 时间:2026-09-15
-
- 以下哪种粮食是酿造绍兴黄酒的主要原料 蚂蚁庄园今日答案9月16日
- 时间:2026-09-15
-
- 劝学名句“及时当勉励,岁月不待人”出自哪位诗人 蚂蚁庄园今日答案9.16
- 时间:2026-09-15
-
- 蚂蚁庄园今天答题答案2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园答题今日答案2026年9月16日
- 时间:2026-09-15
