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>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。