上次遇到一個導入時需要獲取剛插入的數據並在次表存上一條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的返回值類型。
以上皆為個人理解和查詢結果,歡迎批評指正~~