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

selectKey返回最近一次插入的id

返回自增ID

    <selectKey resultType="java.lang.Integer" keyProperty="id" order="BEFORE" >//AFTERSELECT LAST_INSERT_ID()</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代码:

XML代码
<insert id="insert" parameterType="SysUser" >
< selectKey keyProperty="id" order="BEFORE" resultType="java.lang.string">select uuid()
</selectKey>
insert into sys_user (id,  name, email, phone)
values (#{id},#{name},#{email},#{phone})
</insert>

应用层代码

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

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

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

<insert id="insert" parameterType="SysUser" >
< selectKey keyProperty="id" order="AFTER" resultType="java.lang.string">select LAST_INSERT_ID()
</selectKey>
insert into sys_user (id,  name, email, phone)
values (#{id},#{name},#{email},#{phone})
</insert>

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

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

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

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

Mybatis 中 selectKey的用法相关推荐

  1. 关于mybatis中selectKey的用法

    在使用MyBatis插入数据进入数据库的时候会用到sequence序列来生成自增的id 这时可以使用selectKey就可以得到sequence的值,同时也会将值返回.不过对于不同的数据库有不同的操作 ...

  2. Mybatis中的foreach用法

    Mybatis中的foreach用法 目录 Mybatis中的foreach用法 元素属性 List对象集合查询 根据数组中的Id删除 update修改 元素属性 item: 集合中元素迭代时的别名, ...

  3. mybatis的selectKey的用法

    Mybatis 示例之 SelectKey SelectKey在Mybatis中是为了解决Insert数据时不支持主键自动生成的问题,他可以很随意的设置生成主键的方式. 不管SelectKey有多好, ...

  4. MyBatis中foreach元素用法解析

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/70946761冷血之心的博客)          动态SQL是MyB ...

  5. mybatis中selectKey的作用

    selectKey的作用 属性 作用 keyProperty selectKey 语句结果应该被设置的目标属性 resultType mybatis中,返回值类型 order 可以被设置为 BEFOR ...

  6. mybatis 中 if else 用法

    mybaits 中没有 else 要用 chose when otherwise 代替 下面就是MyBatis中的if....else...表示方法 <choose><when te ...

  7. Mybatis中parameterType的用法

    在mybatis映射接口的配置中,有select,insert,update,delete等元素都提到了parameterType的用法,parameterType为输入参数,在配置的时候,配置相应的 ...

  8. Mybatis中的association用法

    这篇文章我们将来学习一些 association 用法 表结构 DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` int(11 ...

  9. Mybatis中Example的用法

    Example简单介绍 1.example是Mybatis数据层框架中的一个工具,可以帮我们完成sql语句中where条件句的书写,相当于where后面的部分,我们可以根据不同的条件来查询和操作数据库 ...

最新文章

  1. RAC环境下的备份与恢复(一)
  2. 应用程序模块和实体缓存
  3. java 批量处理 示例_Java中异常处理的示例
  4. Swift-属性监听
  5. php 标点符号,php 过滤英文标点符号及过滤中文标点符号代码
  6. Android之个性化ListView实现
  7. jenkins重启 linux_在Linux中,Jenkins无法启动
  8. Centos7 防火墙操作及端口查询
  9. android数据存放map_Android存储数据到本地文件
  10. 蛮力法求最大字段和时间复杂度_蛮力法
  11. CB Loss:基于有效样本的类别不平衡损失
  12. app_offline.htm的作用
  13. ASIO音频驱动开发指南 2.0
  14. pandas-task08-文本数据.md
  15. java convexhull_android java opencv 2.4 convexhull convexdefect
  16. 技嘉b365m小雕驱动工具_【黑苹果】技嘉B365M小雕+i5 9400F+RX590EFI分享
  17. [每天一个知识点]12-Maven怎么读
  18. UI设计中异常状态设计总结
  19. 关于Provision.apk
  20. 北航计算机学院学硕分数,考研|北航各学院复试分数线陆续公布,原来这个专业分数最高!...

热门文章

  1. DPDK - 通过源码安装dpdk并运行examples (by quqi99)
  2. android开发板配ip,itop4412开发板-Android4.4-设置静态IP
  3. 阶段三:JAVAWeb
  4. CDGA/CDGP数据治理认证班将于2/4正式开课,报名从速!
  5. 并发编程专题五-AbstractQueuedSynchronizer源码分析
  6. windows搭建ftp服务器、抓取虚拟机数据包、局域网流量监听
  7. 两个聊天机器人的情话--今天打开淘宝旺旺看到聊天机器人,于是聊了两句,很有趣.........
  8. linux红帽5安装,RedHat Linux 5安装手册
  9. 错误: 找不到或无法加载主类 com.ssw.Springboot04Application
  10. Arm Mbed OS 更适合大学实训平台