当前位置:   article > 正文

Mybatis 中 selectKey的用法_mybatis selectkey

mybatis selectkey

大家好,我们今天来看下mysql中selectKey的用法。

selectKey返回最近一次插入的id

返回自增ID

  1. <selectKey resultType="java.lang.Integer" keyProperty="id" order="BEFORE" >//AFTER
  2. SELECT LAST_INSERT_ID()
  3. </selectKey>

项目中出现的问题:主子表入库时,子表需要主表中的id,当selectKey的order参数设置为BEFORE,获取到的id为0,导致向子表插入数据时出现主键重复的问题。解决方法将BEFORE改为AFTER

先看下selectKey的解释:

主要原因是因为BEFORE是先查最近插入一条的id,在进行插入,把BEFORE改为AFTER就可以解决这个问题。下面我们讨论一下为什么

我们来复现下这个问题

重启项目后第一次操作时总是会出现主键重复的问题,但是从第二操作就会神奇的成功

主表数据中最新的一条数据是applyId为210的数据,主键为自增

第一次进行数据入库

主表插入数据之后,根据SELECT LAST_INSERT_ID()  返回的applyId为0,正常来讲应该返回插入之后的主键211

图一:

由于子表插入失败,事务回滚主表中最新的一条数据还是主键为210的数据

图二:

 

第二次进行数据入库操作;操作子表插入

主表插入数据之后,根据SELECT LAST_INSERT_ID()  返回的applyId为211,正常来讲应该返回插入之后的主键212,图二中可以看到主表中并没有主键为211的数据。由此可见返回的并非插入到数据库中最近插入数据的主键,不管事务有没有提交成功,但是主键自增过,进行insert操作过,返回的就是最近执行insert中的主键。

图三:

数据库中的数据:我们发现主表中的id是212,但是子表中插入的主键是211

图五:

为什么会出现这种情况,原因是因为mysql 的select   LAST_INSERT_ID()语句。

在一个新的statement 中 执行 select     LAST_INSERT_ID() 返回为0,但是执行过一次insert语句后,再次执行select     LAST_INSERT_ID() 返回的是最新一次插入数据的id。

那么order属性设置为BEFORE这个就是先执行LAST_INSERT_ID()再去操作插入语句,而AFTER正好相反。

如果数据库中id为自增的方式,将selectKey的order参数置为AFTER才会返回正确的结果

2. 关于生成UUid 返回生成uuid

xml代码:

  1. XML代码
  2. <insert id="insert" parameterType="SysUser" >
  3. < selectKey keyProperty="id" order="BEFORE" resultType="java.lang.string">
  4. select uuid()
  5. </selectKey>
  6. insert into sys_user
  7. (id, name, email, phone)
  8. values
  9. (#{id},#{name},#{email},#{phone})
  10. </insert>

应用层代码 

  1. SysUser user=new SysUser();
  2. user.setId("354646465465465464sdfasdfasdfasdf");
  3. user.setName("测试");
  4. user.setEmail("11@qq.com");
  5. user.setPhome("15866669999");
  6. sysUserDao.insert(user);

 数据库结果,我们可以看出,数据库中的id并不是在应用层给赋值的那个id,而是执行select uuid() 的结果作为user的id。

关于生成uuid的方式,BEFORE是先设置完成id之后进行插入操作。

  1. <insert id="insert" parameterType="SysUser" >
  2. < selectKey keyProperty="id" order="AFTER" resultType="java.lang.string">
  3. select LAST_INSERT_ID()
  4. </selectKey>
  5. insert into sys_user
  6. (id, name, email, phone)
  7. values
  8. (#{id},#{name},#{email},#{phone})
  9. </insert>

可以看到数据库中插入的id就是自己设置的id但是执行SELECT LAST _INSERT_ID()返回的始终都是0。

以上两种情况可以看出,BEFORE适合使用在设置UUID的情况,AFTER适合使用在返回自增id的情况

两者搭配的语句也不同,BEFORE===SELECT UUID()   ,AFTER===SELECT LAST_INSERT_ID(); 

以上就是本文讨论的,欢迎大家指出问题,共同进步

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/241393
推荐阅读
相关标签
  

闽ICP备14008679号