详解Java MyBatis 插入数据库返回主键

 更新时间:2017年01月03日 08:16:22   作者:星云博客园  
这篇文章主要介绍了详解Java MyBatis 插入数据库返回主键,有兴趣的可以了解一下。

最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记。

类似下面这段代码一样获取插入后的主键

User user = new User(); 
user.setUserName("chenzhou"); 
user.setPassword("xxxx"); 
user.setComment("测试插入数据返回主键功能"); 
 
System.out.println("插入前主键为:"+user.getUserId()); 
userDao.insertAndGetId(user);//插入操作 
System.out.println("插入后主键为:"+user.getUserId()); 

经过查询网上资料,发现大致有两种方式。

方式一:

在实体类的映射文件 "*Mapper.xml" 这样写:

<insert id="insertAndGetId" useGeneratedKeys="true" keyProperty="userId" parameterType="com.chenzhou.mybatis.User">
  insert into user(userName,password,comment)
  values(#{userName},#{password},#{comment})
</insert>

Tips:

useGeneratedKeys="true" 表示给主键设置自增长

keyProperty="userId"  表示将自增长后的Id赋值给实体类中的userId字段。

parameterType="com.chenzhou.mybatis.User" 这个属性指向传递的参数实体类

这里提醒下,<insert></insert> 中没有resultType属性,不要乱加。

实体类中uerId 要有getter() and setter(); 方法

由于我在MySQL数据库中建表时候已经设置了字段自增长,故最终我选择了第二种方式。

第二种方式:

同样在实体类的映射文件 "*Mapper.xml" 但是要这样写:

  <!-- 插入一个商品 -->
  <insert id="insertProduct" parameterType="domain.model.ProductBean" >
    <selectKey resultType="java.lang.Long" order="AFTER" keyProperty="productId">
     SELECT LAST_INSERT_ID()
   </selectKey>
    INSERT INTO t_product(productName,productDesrcible,merchantId)values(#{productName},#{productDesrcible},#{merchantId});
  </insert>

Tips:

<insert></insert> 中没有resultType属性,但是<selectKey></selectKey> 标签是有的。

order="AFTER" 表示先执行插入语句,之后再执行查询语句。

可被设置为 BEFORE 或 AFTER。

如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。

如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素-这和如 Oracle 数据库相似,可以在插入语句中嵌入序列调用
keyProperty="userId"  表示将自增长后的Id赋值给实体类中的userId字段。

SELECT LAST_INSERT_ID() 表示MySQL语法中查询出刚刚插入的记录自增长Id.

实体类中uerId 要有getter() and setter(); 方法

实现需求,上面那些就足够了。

这里如果有兴趣的,请继续听我讲一个Mybatis中可能误入的坑。

为什么Mybatis 中修改添加方法为有返回值后,虽然提示插入数据库成功并且也能读取插入的数据,但是当你打开数据库后就是看不到插入的数据?

如果在实现上述需求时,想插入后返回主键的话,切记不要这样写。

  @Override
  public Long insertProduct(ProductBean productBean) {
    // TODO Auto-generated method stub
    SqlSession session = MybatisJDBCUtil.currentSession();

    ProductIDao productIDao = session.getMapper(ProductIDao.class);// 这里*.class
                                    // 必须对应DAO的接口层
    return productIDao.insertProduct(productBean);
    
  }

Why?

因为如果你是像上面这样写,那么执行后返回的也不是你想要的主键Id,而是执行数据库语句后受影响的行数。

而且,当你执行后你会发现提示插入成功,你用代码也可以读取出插入的数据,但是永远只有一条记录。

并且,你打开数据库会发现,数据库中没有插入成功任何数据。

我在这里郁闷了N久,终于发现了关键所在。

有返回值和没返回值的区别在于:

有返回值的只是对数据库只读模式访问数据库,对数据库数据不会有任何修改,比如各种方式的查询。

无返回值的则会以读写模式访问数据库,会对数据库中的数据进行修改,比如删除,增加。

除此之外,根据个人理解应该mybatis在执行插入语句时会先缓存到构造的一个类似session集合中,然后才去调用底层驱动去操作修改数据库。

session.commit();    
MybatisJDBCUtil.closeSession();

没有返回值得才有上面这两条语句,也就是说执行了这两条语句才会真正执行插入到数据库,对数据库的数据进行修改。

相反,有返回值的就没有执行这两条语句,所以只是在自己构造的session中执行了添加语句,但是并没有提交到数据库中,故数据库中是没有任何记录的。

这也就解释了为什么Mybatis 中修改添加方法为有返回值后,虽然提示插入数据库成功,但是当你打开数据库看不到插入的数据。

Mybatis中插入语句方法种不要有返回值,像这样写是正确的。

  @Override
  public void insertProduct(ProductBean productBean) {
    // TODO Auto-generated method stub
    SqlSession session = MybatisJDBCUtil.currentSession();

    ProductIDao productIDao = session.getMapper(ProductIDao.class);// 这里*.class
                                   // 必须对应DAO的接口层
    productIDao.insertProduct(productBean);
    
    session.commit(); 
    
    MybatisJDBCUtil.closeSession();  
  }

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

相关文章

  • 微信小程序 springboot后台如何获取用户的openid

    微信小程序 springboot后台如何获取用户的openid

    这篇文章主要介绍了微信小程序 springboot后台如何获取用户的openid,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • SpringBoot整合mybatis-plus快速入门超详细教程

    SpringBoot整合mybatis-plus快速入门超详细教程

    mybatis-plus 是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生,本文给大家分享SpringBoot整合mybatis-plus快速入门超详细教程,一起看看吧
    2021-09-09
  • SpringBoot Mybatis Plus公共字段自动填充功能

    SpringBoot Mybatis Plus公共字段自动填充功能

    这篇文章主要介绍了SpringBoot Mybatis Plus公共字段自动填充功能的相关资料,需要的朋友可以参考下
    2017-04-04
  • Scala方法与函数使用和定义详解

    Scala方法与函数使用和定义详解

    这个章节会很烧脑,需要认真研读,我会尽量写的详细一些。 方法和函数,看似是两个概念,其实他严格来说也是两个概念,但我们大可以理解成是同一个概念,在使用时只有语法上的细微差别,是很类似的,都理解为function即可
    2022-12-12
  • java中的Io(input与output)操作总结(二)

    java中的Io(input与output)操作总结(二)

    这一节我们来讨论关于文件自身的操作包括:创建文件对象、创建和删除文件、文件的判断和测试、创建目录、获取文件信息、列出文件系统的根目录、列出目录下的所有文件,等等,感兴趣的朋友可以了解下
    2013-01-01
  • 浅谈java中的路径表示

    浅谈java中的路径表示

    下面小编就为大家带来一篇浅谈java中的路径表示。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • SpringBoot实现自动配置的示例代码

    SpringBoot实现自动配置的示例代码

    本文主要介绍了SpringBoot实现自动配置的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-01-01
  • 一文搞懂Java中的序列化与反序列化

    一文搞懂Java中的序列化与反序列化

    序列化是将对象转换成二进制字节流的过程;反序列化是从二进制字节流中恢复对象的过程。文中降通过示例详解二者的使用与区别,需要的可以参考一下
    2022-08-08
  • Windows系统中Java调用cmd命令及执行exe程序的方法

    Windows系统中Java调用cmd命令及执行exe程序的方法

    这篇文章主要介绍了Windows系统中Java调用cmd命令及执行exe程序的方法,主要用到了IOException类,需要的朋友可以参考下
    2016-03-03
  • java数据结构基础:循环链表和栈

    java数据结构基础:循环链表和栈

    这篇文章主要介绍了Java数据结构之循环链表、栈的实现方法,结合实例形式分析了Java数据结构中循环链表、栈、的功能、定义及使用方法,需要的朋友可以参考下
    2021-08-08

最新评论