mybatis插入数据不返回主键id的可能原因及解决方式

 更新时间:2023年08月31日 17:00:48   作者:宋峥清  
这篇文章主要介绍了mybatis插入数据不返回主键id的可能原因及解决方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

mybatis插入数据不返回主键id原因及解决

mybatis插入数据返回主键id这个特性很好用,但是不注意细节的话很容易拿不到主键id,因此这篇文章比较全面的讲解下,拿不到主键id的可能因素和解决方案。

1.xml是否配置返回主键id

普通插入数据的xml如下:

<insert id="addUser">
	INSERT INTO user(name,age)
	VALUES(#{name},#{age})
</insert>

这是一个新增用户的xml如果想要新增后返回用户id进行下一步业务操作,有两个属性是必不可少的

useGeneratedKeys="true" keyProperty="id" 

这两个属性意思为:如果表中新增数据自增主键是【id】的话,就会把主键id返回

所以如果没有返回,或者想要返回数据主键id,这两个属性必不可少

2.dao类入参名称是否额外配置

普通dao类如下:

UserDao 或者 UserMapper类有个新增用户的方法,以下统称UserDao(字数少…)

int addUser(User user);

相对应的是xml文件中方法:

<insert id="addUser" useGeneratedKeys="true" keyProperty="id">
	INSERT INTO user(name,age)
	VALUES(#{name},#{age})
</insert>

参照以上写法,在添加用户后,会通过【keyProperty】属性把用户id给映射到User类中的id去,这样子是能拿到id的

但是如果UserDao添加用户方法是以下这种方式:

多了个@Param注解

int addUser(@Param("user")User user);

那么相对应xml中的【keyProperty】属性也需要通过转化为@Param中的名称去引用id,不然mybatis不知道把返回的id映射到哪个字段去,

正确如下:

<insert id="addUser" useGeneratedKeys="true" keyProperty="user.id">
	INSERT INTO user(name,age)
	VALUES(#{user.name},#{user.age})
</insert>

有种马虎的写法是这种,【keyProperty】没有使用UserDao添加用户@Param的别名去引用id,所以获取不到主键id:

错误的:!!!!
<insert id="addUser" useGeneratedKeys="true" keyProperty="id">
	INSERT INTO user(name,age)
	VALUES(#{user.name},#{user.age})
</insert>

3.排除以上两种,请检查获取主键id的业务代码

这个问题导致的可能性比较低,一般来说是不太可能会发展,但是也架不住的确发生了(比如我…)

上错误业务代码:

 //问题代码
 //添加用户
 User user = User.builder().name("小红").age(18).build();
 int userId = userDao.addUser(user);
 //将用户设置为管理员
 roleDao.setManager(userId);
 	.......

乍一看,貌似没问题,但是…有时候写curd脑子没有转过来的话,就犯下了这种错误

新增用户后返回的主键id,并不是通过userDao.addUser()方法返回来的,这里返回的是数据库数据的影响行数,因此一直返回值是1的时候我惊呆了,一直在想为什么以前dao层这么写能获取呢????后面上个厕所再仔细看代码就明白了。。。。

新增用户后立即返回的主键id是帮你直接映射到用户类的id属性去了,所以是通过userDao.addUser(user);里面的user.getId();才能拿到

正确代码如下:

 //添加用户
 User user = User.builder().name("小红").age(18).build();
 userDao.addUser(user);
 //将用户设置为管理员
 //获取用户id
 int userId = user.getId();
 roleDao.setManager(userId);
 	.......

问题出现的方式形式奇奇怪怪,最重要的还是要保持脑袋的清醒,也侧面说了一件事,写代码是个精细活,半点马虎都犯不得,犯了就找bug吧~

mybatis插入数据后返回自增主键ID失败总结

问题代码如下

void insert(@param("user")User user);
 <!-- 插入数据:返回记录主键id值 -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id"  keyColumn="id">
        insert  into t_user (name,age) values (#{user.name},#{user.age})
</insert>

执行sql后,user.getId()并没有返回自增ID,自以为自增配置也没问题

  • useGeneratedKeys为true,用来设置返回主键id的值,
  • keyProperty代表 java对象成员属性名
  • keyColumn代表数据库记录主键字段

最后实践发现因为insert方法钟使用了@param注解,keyProperty 应该设置为user.id

r如下

 <!-- 插入数据:返回记录主键id值 -->
<insert id="insert" useGeneratedKeys="true" keyProperty="user.id"  keyColumn="id">
        insert  into t_user (name,age) values (#{user.name},#{user.age})
</insert>

或者修改方法和sql

void insert(User user);
 <!-- 插入数据:返回记录主键id值 -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id"  keyColumn="id">
        insert  into t_user (name,age) values (#{name},#{age})
</insert>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java8通过Function获取字段名的步骤

    Java8通过Function获取字段名的步骤

    这篇文章主要介绍了Java8通过Function获取字段名,需要的朋友可以参考下
    2020-04-04
  • springboot实现定时任务的四种方式小结

    springboot实现定时任务的四种方式小结

    本文主要介绍了springboot实现定时任务的四种方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • idea中启动项目弹出 IDEA out of memory窗口的解决方案

    idea中启动项目弹出 IDEA out of memory窗口的解决方案

    这篇文章主要介绍了idea中启动项目弹出 IDEA out of memory窗口的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • SpringBoot Feign使用教程超全面讲解

    SpringBoot Feign使用教程超全面讲解

    现在的微服务项目不少都使用的是springboot+Feign构建的项目,微服务之间的调用都离不开feign来进行远程调用,这篇文章主要介绍了SpringBoot Feign使用教程,需要的朋友可以参考下
    2022-11-11
  • Java 数据结构与算法系列精讲之数组

    Java 数据结构与算法系列精讲之数组

    数组是有序的元素序列,若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式
    2022-02-02
  • SpringSecurityOAuth2实现微信授权登录

    SpringSecurityOAuth2实现微信授权登录

    微信的登录功能是用户注册和使用微信的必经之路之一,而微信授权登录更是方便了用户的登录操作,本文主要介绍了SpringSecurityOAuth2实现微信授权登录,感兴趣的可以了解一下
    2023-09-09
  • 使用Java对PDF添加水印的操作代码

    使用Java对PDF添加水印的操作代码

    在当今数字化办公环境中,PDF 文档作为信息交流和存储的重要载体,其安全性和版权保护变得尤为关键,企业常常需要对内部敏感文档或对外发布的资料添加水印,以防止未经授权的使用,本文将为您揭示这一问题的解决方案,深入探讨如何使用Java对PDF添加水印,需要的朋友可以参考下
    2025-10-10
  • springboot自定义拦截器简单使用及举例

    springboot自定义拦截器简单使用及举例

    Spring Boot拦截器是AOP的一种实现,专门拦截对控制层的请求,主要应用于判断用户权限,拦截webSocket请求,下面这篇文章主要给大家介绍了关于springboot自定义拦截器简单使用及举例的相关资料,需要的朋友可以参考下
    2023-01-01
  • java web用servlet监听器实现显示在线人数

    java web用servlet监听器实现显示在线人数

    这篇文章主要为大家详细介绍了java web用servlet监听器实现显示在线人数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • javaweb如何实现请求和响应

    javaweb如何实现请求和响应

    这篇文章主要为大家详细介绍了javaweb如何实现请求和响应,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10

最新评论