详解MyBatis中主键回填的两种实现方式

 更新时间:2019年04月24日 09:29:47   作者:江南一点雨  
这篇文章主要介绍了详解MyBatis中主键回填的两种实现方式,主键回填其实是一个非常常见的需求,特别是在数据添加的过程中,我们经常需要添加完数据之后,需要获取刚刚添加的数据 id,有兴趣的可以参考一下

主键回填其实是一个非常常见的需求,特别是在数据添加的过程中,我们经常需要添加完数据之后,需要获取刚刚添加的数据 id,无论是 Jdbc 还是各种各样的数据库框架都对此提供了相关的支持,本文我就来和和大家分享下数据库主键回填在 MyBatis 中的两种实现思路。

原生写法

框架来源于我们学过的基础知识,主键回填实际上是一个在 JDBC 中就被支持的写法,有的小伙伴可能不知道这一点,因此这里我先来说说在 JDBC 中如何实现主键回填。

JDBC 中实现主键回填其实非常容易,主要是在构造 PreparedStatement 时指定需要主键回填,然后在插入成功后,查询刚刚插入数据的 id ,示例代码如下:

public int insert(Person person) {
  Connection con = null;
  PreparedStatement ps = null;
  ResultSet rs = null;
  con = DBUtils.getConnection();
  ps = con.prepareStatement("INSERT INTO person(username,password,money) VALUES(?,?,?)", PreparedStatement.RETURN_GENERATED_KEYS);
  ps.setObject(1, person.getUsername());
  ps.setObject(2, person.getPassword());
  ps.setObject(3, person.getMoney());
  int i = ps.executeUpdate();
  rs = ps.getGeneratedKeys();
  int id = -1;
  if (rs.next()) {
    id = rs.getInt(1);
  }
  return id;
}

和普通的插入 SQL 不同之处主要体现在两个地方:

  • 第一个是构造 PreparedStatement 时,多了一个参数,指定了需要主键回填。
  • 在更新操作执行完成之后,调用 getGeneratedKeys ,然后又会获取到一个 ResultSet 对象,从这个游标集中就可以获取到刚刚插入数据的id。

这个是原生的写法,在 MyBatis 中,对此需求提供了两种不同的实现方案,下面分别来看。

框架写法

一般情况下,主键有两种生成方式:

  1. 主键自增长
  2. 自定义主键(一般可以使用UUID,或者类UUID)

如果是第二种,主键一般是在Java代码中生成,然后传入数据库执行插入操作,如果是第一个主键自增长,此时,Java 可能需要知道数据添加成功后的主键。

MyBatis 的基本用法就无需多说了,这也不是本文的重点,我们还是来看看 MyBatis 中主键回填的两种不同实现方式吧!

方式一

第一种方式比较简单,也是松哥推荐的一种实现方式:

<insert id="insertBook" useGeneratedKeys="true" keyProperty="id">
  insert into t_book (b_name,author) values (#{name},#{author});
</insert>

这种方式比较简单,就是在插入节点上添加 useGeneratedKeys 属性,同时设置接收回传主键的属性。配置完成后,我们执行一个插入操作,插入时传入一个对象,插入完成后,这个对象的 id 就会被自动赋值,值就是刚刚插入成功的id。

推荐大家使用这种方式,原因很简单,这种方式实现简便省事。

方式二

第二种方式则是利用MySQL自带的 last_insert_id() 函数查询刚刚插入的id,示例代码如下:

<insert id="insertBook">
  <selectKey keyProperty="id" resultType="java.lang.Integer">
    SELECT LAST_INSERT_ID()
  </selectKey>
  insert into t_book (b_name,author) values (#{name},#{author});
</insert>

这种方式是在 insert 节点中添加 selectKey 来实现主键回填,实际上这种方式的功能更加丰富,因为 selectKey 节点中的 SQL 我们既可以在插入之前执行,也可以在插入之后执行(通过设置节点的 Order 属性为 AFTER 或者 BEFORE 可以实现),具体什么时候执行,还是要看具体的需求,如果是做主键回填,我们当然需要在插入 SQL 执行之后执行 selectKey 节点中的 SQL。

注意第二种方式一样也要通过设置 keyProperty 来指定将查询到的数据绑定到哪个属性上。

总结

好了,本文向大家介绍了 MyBatis 中主键回填的两种方式,大家有没有 get 到呢?有问题欢迎留言讨论。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java使用雪花id生成算法详解

    Java使用雪花id生成算法详解

    SnowFlake算法,是Twitter开源的分布式id生成算法,在2014年开源,开源的版本由scala编写。其核心思想就是-使用一个64bit的long型的数字作为全局唯一id
    2022-12-12
  • Spring MVC 拦截器实现代码

    Spring MVC 拦截器实现代码

    本篇文章主要介绍了Spring MVC 拦截器的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-02-02
  • Java多线程并发编程 并发三大要素

    Java多线程并发编程 并发三大要素

    这篇文章主要介绍了Java多线程并发编程 并发三大要素,需要的朋友可以参考下
    2017-05-05
  • MyBatis 如何简化的 JDBC(思路详解)

    MyBatis 如何简化的 JDBC(思路详解)

    MyBatis 是一个 持久层 框架,用于 简化JDBC开发,这篇文章主要介绍了MyBatis 如何简化的 JDBC(思路详解),需要的朋友可以参考下
    2023-03-03
  • MyBatis typeHandler接口的定义和使用

    MyBatis typeHandler接口的定义和使用

    TypeHandler被称作类型处理器,MyBatis在设置预处理语句中的参数或从结果集中取出一个值时,都会用类型处理器将Java对象转化为数据库支持的类型或者将获取到数据库值以合适的方式转换成Java类型,感兴趣的同学可以参考下文
    2023-05-05
  • SpringBoot使用druid配置多数据源问题

    SpringBoot使用druid配置多数据源问题

    这篇文章主要介绍了SpringBoot使用druid配置多数据源问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Java 中的 String对象为什么是不可变的

    Java 中的 String对象为什么是不可变的

    String对象是不可变的,但这仅意味着你无法通过调用它的公有方法来改变它的值。本文给大家介绍java中的string对象为什么是不可变的,需要的朋友一起了解了解吧
    2015-10-10
  • 浅析Java迭代器Iterator和Iterable的区别

    浅析Java迭代器Iterator和Iterable的区别

    Java语言中,Iterator和Iterable都是用来遍历集合类数据结构的接口,虽然它们有很多相似的地方,但在具体实现中却有着一些不同之处,本文将详细分析它们的区别,并提供相应的代码示例,需要的朋友可以参考下
    2023-07-07
  • 关于PreparedStatement的setObject作用及说明

    关于PreparedStatement的setObject作用及说明

    这篇文章主要介绍了关于PreparedStatement的setObject作用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • SpringBoot使用Mybatis-Generator配置过程详解

    SpringBoot使用Mybatis-Generator配置过程详解

    这篇文章主要介绍了SpringBoot使用Mybatis-Generator配置过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02

最新评论