在使用主键自增(如 MySQL、 SQL Server 数据库)时,插入数据库后可能需要得到自增的
主键值,然后使用这个值进行一些其他的操作。现在,增加一个 insert2 方法
然后在 XML 中新增一个 insert2 方法 。
<insert i d=” insert2 ” useGeneratedKeys=” true ” keyProperty=” id” >
insert into sys_user
(user_name,user_password,user_email,user_info,head_img,create_time)
values
( #{userName} , #{userPassword},#{userEmail},
#{userinfo},#{headimg, jdbcType=BLOB},
#{createTime,jdbcType= TIMESTAMP} )
</insert>
将 insert2 和 insert 比较,主要的变化是在 insert 标签上配置了如下两个属性。
- useGeneratedKeys=” true ”
- keyProperty=” id”
useGeneratedKeys 设置为 true 后, MyBatis 会使用 JDBC 的 getGeneratedKeys 方
法来取出 由数据库内部生成的主键。获得主键值后将其赋值给 keyProperty 配置的 id 属性。
当需要设置多个属性时,使用逗号隔开,这种情况下通常还需要设置 keyColumn 属性 , 按顺
序指定数据库的列,这里列的值会和 keyProperty 配置的属性一一对应。
上面这种回写主键的方法只适用于支持主键自增的数据库。有些数据库(如 Oracle )不提
供主键自增的功能,而是使用序列得到一个值,然后将这个值赋给 id,再将数据插入数据库 。
对于这种情况,可以采用另外一种方式:使用<selectKey>标签来获取主键的值,这种方式不
仅适用于不提供主键自增功能的数据库,也适用于提供主键自增功能的数据库 。
mysql示例
<insert i d=” insert3 ” useGeneratedKeys=” true ” keyProperty=” id” >
insert into sys_user
(user_name,user_password,user_email,user_info,head_img,create_time)
values
( #{userName} , #{userPassword},#{userEmail},
#{userinfo},#{headimg, jdbcType=BLOB},
#{createTime,jdbcType= TIMESTAMP} )
<selectKey keyColumn=” id” resultType=” long” keyProperty=” id” order=” AFTER” >
SELECT LAST INSERT ID ()
</selectKey>
</insert>
注意看下面这段代码,和 insert 相比增加了 selectKey 标签 。
<selectKey keyColumn=” id” resultType=” long” keyProperty=” id” order=” AFTER” >
SELECT LAST INSERT ID ()
</selectKey>
selectKey 标签 的 ke yColumn 、 keyProperty 和上面 useGeneratedKeys 的用法含
义相同 ,这里的 resultType 用于设置返回值类型 。 order 属性的设置和使用的数据库有关 。
在 MySQL 数据库中, order 属性设置的值是 AFTER,因为当前记录的主键值在 insert 语句
执行成功后才能获取到 。 而在 Oracle 数据库中, order 的值要设置为 BEFORE ,这是因为 Oracle
中需要先从序列获取值,然后将值作为主键插入到数据库中 。
Oracle示例
<insert id=” insert3” >
<selectKey keyColumn= ” id” resultType= ” long ” keyProperty= ” id” order= ” BEFORE ” 〉
SELECT SEQ ID.nextval from dual
insert into sys_user
(id,user_name,user_password,user_email,user_info,head_img,create_time)
values
( #{id} , #{userName} , #{userPassword},#{userEmail},
#{userinfo},#{headimg, jdbcType=BLOB},
#{createTime,jdbcType= TIMESTAMP} )
</insert>
Oracle 方式的副SERT 语句中明确写出了 id 和值#{id},因为执行 selectKey 中的
语句后 id 就有值了,我们需要把这个序列值作为主键值插入到数据库中,所以必须指定 id
列,如果不指定这一列,数据库就会因为主键不能为空而抛出异常 。
在 Oracle 示例中, SELECT SEQ_ ID.nextval from d ual
是一个获取序列的 SQL 语句。 MySQL 中的 SQL 语句 SELECT LAST_ INSERT_ID ()用于获取
数据库中最后插入的数据的 ID 值