一般的insert操作返回的是受影响行数,如果要获得新增加的那一行的主键,有两种方式可以实现。
方法1(推荐):
<insert id="addAuthor" parameterType="domain.Author" useGeneratedKeys="true" keyProperty="id"> insert into author(username,password,email,bio) values(#{username},#{password},#{email},#{bio}) </insert>
方法2(依赖于使用的数据库):
<insert id="addAuthor" parameterType="domain.Author"> <selectKey resultType="java.lang.Integer" keyProperty="id" order="AFTER" > SELECT @@IDENTITY AS id </selectKey> insert into author(username,password,email,bio) values(#{username},#{password},#{email},#{bio}) </insert>
结果:调用mapper接口返回的依然是受影响行数,但是主键已经赋值到parameterType对应的实体类的属性中了 ,直接调用就可以了。
要弄清楚上面的实现方式,要先知道下面这些东西:
1.insert标签的属性
keyProperty ,默认值unset,用于设置getGeneratedKeys方法或selectKey子元素返回值将赋值到领域模型的哪个属性中
useGeneratedKeys ,取值范围true|false(默认值),设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。MySQL和SQLServer执行auto-generated key field,因此当数据库设置好自增长主键后,可通过JDBC的getGeneratedKeys方法获取。但像Oralce等不支持auto-generated key field的数据库就不能用这种方法获取主键了。
2.selectKey标签的属性
keyProperty ,默认值unset,用于设置getGeneratedKeys方法或selectKey子元素返回值将赋值到领域模型的哪个属性中
resultType ,keyPropety所指向的属性类全限定类名或类型别名
order属性 ,取值范围BEFORE|AFTER,指定是在insert语句前还是后执行selectKey操作
statementType ,取值范围STATEMENT,PREPARED(默认值),CALLABLE
3.select @@identity的用法
用select @@identity得到上一次插入记录时自动产生的ID。
在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。若 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。