这是mybatis系列第六篇。没看前文的建议先去【Java冢狐】公众号中查看前文,方便理解和掌握。
前面五篇把MyBatis的基本用法基本介绍完毕了,强烈推荐大家先把前面五篇看完实际操作完再来看接下来的内容。
增删改返回值说明
mybatis中对db执行增删改操作,不管是新增、删除、还是修改,其本质都是使用jdbc中对应的方法,即java.sql.Statement的executeUpdate的方法,或者java.sql.PreparedStatement的executeUpdate方法。
所以问题的关键在于掌握这两个方法的内容,而这两个方法的参数不一致但是返回值都是int,用来表示影响的行数。
而Mybatis的返回值再支持int的基础上,还支持Integer、long、Long、boolean、Boolean、void多种类型,可谓是大大加强了编程的灵活性和多样性。
但是聪明的小伙伴肯定知道,MyBatis能支持这么多种的类型,其实就是mybatis在内部将int类型转换成其他类型而已。没有什么高深的东西、
了解了增删改查的返回值后,下一步我们再去看一看jdbc和mybatis是如何获取主键的。
jdbc获取主键的几种方式
在聊jdbc获取主键的方式之前,我们先来回想一下数据库的主键是怎么样生成的。
那mysql举例:在mysql中当我们向表中插入数据的时候,如果不指定主键(id),那么mysql会自动生成id,但是在一些业务中我们后续会需要这个id,此时我们就要想办法去获取这个id,尤其是这种自动生成的自增id。
要想要清楚的了解,就需要先看看jdbc是如何实现的
方式1:jdbc内置的方式
用法
获取主键的需求,jdbc的开发人员就已经想到了,并且也开发了相应的api来帮助我们编程,具体看 java.sql.Statement类中的getGeneratedKeys方法
从这个方法中我们得知这个方法会返回一个结果集,从这个结果集中可以获取自增主键的值。但是在使用这个方法有个前提,那就是执行sql的时候需要做一个设置。
如果是通过java.sql.Statement执行sql,需要调用下面这个方法:
int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException
注意上面这个方法的第二个参数需要设置为java.sql.Statement.RETURN_GENERATED_KEYS,表示需要返回自增列的值。
不过多数情况下,我们会使用java.sql.PreparedStatement对象来执行sql,如果想获取自增值,创建这个对象需要设置第2个参数的值,如下:
PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
然后我们就可以通过getGeneratedKeys返回的ResultSet对象获取自动增长的值了,如下:
ResultSet generatedKeys = preparedStatement.getGeneratedKeys(); if (generatedKeys!=null && generatedKeys.next()) { log.info("自增值为:{}", generatedKeys.getInt(1)); }
方式2:插入之后查询获取
用法
当然除了jdbc想到了我们这个需求,mysql数据库也想到了这个需求也有对应的语句来帮助我们在插入数据后获取最新插入记录的id值,如下所示
SELECT LAST_INSERT_ID()
所以我们可以在插入之后,立即使用当前连接发送上面这条sql去获取自增列的值就可以。这种方法相对来说十分的简单和方便,但是也存在着一些问题,就是在高并发多线程的情况 ,可能会出现严重的问题,所以一般来说不建议使用。
方式3:插入之前获取
最后一种方法就是在插入之前获取。
oracle不知道大家有没有玩过,oracle中没有mysql中自动增长列,但是oracle有个功能可以实现自动增长,这个功能就是序列,序列就相当于一个自增器一样,有个初始值,每次递增的步长,当然这个序列提供了一些功能给我们使用,可以获取序列的当前值、下一个值,使用方式如下:
- 先定义一个序列
- 获取下一个值:SELECT 序列名.NEXTVAL FROM dual;
mybatis获取主键的3种方式
既然jdbc有三种方法,那么mybatis也有相应的几种方法。
方式1:内部使用jdbc内置的方式
用法
mybatis这个方式内部采用的是上面说的jdbc内置的方式。
我们需要在Mapper xml中进行配置,如:
<insert id="insertUser1" parameterType="zhonghu.mybatis.chat01.UserModel" useGeneratedKeys="true" keyProperty="id"> <![CDATA[ INSERT INTO user (name,age,salary) VALUES (#{name},#{age},#{salary}) ]]> </insert>
有2个关键参数必须要设置:
- useGeneratedKeys:设置为true
- keyProperty:参数对象中的属性名称,最后插入成功之后,mybatis会通过反射将自增值设置给keyProperty指定的这个属性
方式2:插入后查询获取主键
用法
这个方式和上面介绍的jdbc的第二种方式一样,插入之后通过查询获取主键的值然后填充给指定的属性,mapper xml配置如下:
<insert id="insertUser2" parameterType="zhonghu.mybatis.chat01.UserModel"> <selectKey keyProperty="id" order="AFTER" resultType="long"> <![CDATA[ SELECT LAST_INSERT_ID() ]]> </selectKey> <![CDATA[ INSERT INTO user (name,age,salary) VALUES (#{name},#{age},#{salary}) ]]> </insert>
关键代码是selectKey元素包含的部分,这个元素内部可以包含一个sql,这个sql可以在插入之前或者插入之后运行(之前还是之后通过order属性配置),然后会将sql运行的结果设置给keyProperty指定的属性,selectKey元素有3个属性需要指定:
- keyProperty:参数对象中的属性名称,最后插入成功之后,mybatis会通过反射将自增值设置给keyProperty指定的这个属性
- order:指定selectKey元素中的sql是在插入之前运行还是插入之后运行,可选值(BEFORE|AFTER),这种方式中我们选择AFTER
- resultType:keyProperty指定的属性对应的类型,如上面的id对应的类型是java.lang.Long,我们直接写的是别名long
方式3:插入前查询获取主键
用法
这个方式和上面介绍的jdbc的第3种方式一样,会在插入之前先通过一个查询获取主键的值然后填充给指定的属性,然后在执行插入,mapper xml配置如下:
<insert id="insertUser3" parameterType="zhonghu.mybatis.chat01.UserModel"> <selectKey keyProperty="id" order="BEFORE" resultType="long"> <![CDATA[ 获取主键的select语句 ]]> </selectKey> <![CDATA[ INSERT INTO user (name,age,salary) VALUES (#{name},#{age},#{salary}) ]]> </insert>
关键代码是selectKey元素包含的部分,这个元素内部可以包含一个sql,这个sql可以在插入之前或者插入之后运行(之前还是之后通过order属性配置),然后会将sql运行的结果设置给keyProperty指定的属性,selectKey元素有3个属性需要指定:
- keyProperty:参数对象中的属性名称,最后插入成功之后,mybatis会通过反射将自增值设置给keyProperty指定的这个属性
- order:指定selectKey元素中的sql是在插入之前运行还是插入之后运行,可选值(BEFORE|AFTER),这种方式中我们选择BEFORE
- resultType:keyProperty指定的属性对应的类型,如上面的id对应的类型是java.lang.Long,我们直接写的是别名long
总结
本篇文章着重介绍了mybatis中一些增删改查的高级使用方法,尤其是获取主键的方法,在此进行了jdbc和mybatis对比介绍了三种方法。
最后
- 如果觉得看完有收获,希望能关注一下,顺便给我点个赞,这将会是我更新的最大动力,感谢各位的支持
- 欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我
- 求一键三连:点赞、转发、在看。
- 如果看完有不同的意见或者建议,欢迎多多评论一起交流。感谢各位的支持以及厚爱。
——我是冢狐,和你一样热爱编程。