上次遇到一个导入时需要获取刚插入的数据并在次表存上一条log数据的问题,虽然当时因为需求变更做了些调整,但是此问题还是让我印象深刻。
一、selectKey(通用,但是若是自增主键的数据库,建议第二种方案):
先来看一段映射文件:
<insert id="insert" parameterType="com.sms.intf.model.SMSVerifyAudit"> <selectKey resultType="INTEGER" order="AFTER" keyProperty="id"> SELECT LAST_INSERT_ID() </selectKey> insert into sms_verify_audit (id, user_id, session_id, user_verify_code, status, create_time, user_ip,sms_uuid) values (null, #{userId,jdbcType=VARCHAR}, #{sessionId,jdbcType=VARCHAR}, #{userVerifyCode,jdbcType=VARCHAR}, #{status,jdbcType=TINYINT},now(), #{userIp,jdbcType=VARCHAR},#{smsUuid,jdbcType=VARCHAR}) </insert>
这是我在项目中找到的同事的代码,执行一段插入,出于好奇,查了下各个参数之类的含义,并集合了一些意见:
SELECT LAST_INSERT_ID(): 获取刚刚插入的主键;
keyProperty:表示将返回的值设置到某一列,此处为“id”;
order:表明此代码相对于insert语句的执行顺序,BEFORE(适用于Oralce等取序列的数据库)/ARTER(适用于MySQL等支持自增长的数据库);
resultType:返回的类型;
那么,如何在再代码中获取id呢,只需要在impl中直接用.getId()获取即可:
@Override public int insert(SMSVerifyAudit smsVerifyAudit) { sst.insert(namespace+"insert",smsVerifyAudit); return smsVerifyAudit.getId(); }
二、(支持自增主键的数据库):
这是我在当时根据需求查到的方案,但由于对mybatis的版本有需求(3.3.1),所以当时放弃,但是也作记录:
useGeneratedKeys="true" keyProperty="id"
在mapper映射的插入语句加上这两个属性:
keyProperty:同理依旧为需返回的字段;
userGeneratedKeys:默认为false,只针对于insert语句。true表示插入的表以自增列为主键,则允许 JDBC 支持自动生成主键,并可将自动生成的主键返回;
同理,在impl中:
@Override public List<SMSVerifyAudit> savesmsVerifyAudit(List<smsVerifyAudit> list) { sst.insert(namespace+"insert",list); return list; }
此时的list中已经包含了主键id,只需要获取即可。
此方案单条插入和批量插入皆可使用,主要区别就是mapper的写法和impl的返回值类型。
以上皆为个人理解和查询结果,欢迎批评指正~~