您的位置:首页 >Springboot+MyBatis插入语句返回主键id的问题(插入后返回主键id不是期望的值)
发布于2026-08-05 阅读(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值。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8