一、背景:
SelectKey在Mybatis中是為了解決Insert數(shù)據(jù)時(shí)不支持主鍵自動(dòng)生成的問(wèn)題,他可以很隨意的設(shè)置生成主鍵的方式。
屬性 -描述:
① keyProperty : selectKey 語(yǔ)句結(jié)果應(yīng)該被設(shè)置的目標(biāo)屬性。
② resultType:結(jié)果的類型。MyBatis 通??梢运愠鰜?lái),但是寫上也沒(méi)有問(wèn)題。MyBatis 允許任何簡(jiǎn)單類型用作主鍵的類型,包括字符串。
③ order: 這可以被設(shè)置為 BEFORE 或 AFTER。如果設(shè)置為 BEFORE,那么它會(huì)首先選擇主鍵,設(shè)置 keyProperty 然后執(zhí)行插入語(yǔ)句。如果設(shè)置為 AFTER,那么先執(zhí)行插入語(yǔ)句,然后是 selectKey 元素-這和如 Oracle 數(shù)據(jù)庫(kù)相似,可以在插入語(yǔ)句中嵌入序列調(diào)用。
④ statementType:和前面的相同,MyBatis 支持 STATEMENT ,PREPARED 和CALLABLE 語(yǔ)句的映射類型,分別代表PreparedStatement 和CallableStatement 類型。
二、應(yīng)用場(chǎng)景
使用SELECT LAST_INSERT_ID() 這個(gè)sql語(yǔ)句來(lái)獲取插入記錄后返回的自增id
<insert id="insert" parameterClass="UserDO">
INSERT INTO user( user_id,user_nick,tel_phone,address,status, user_type,remark, gmt_create, gmt_modified)
VALUES ( #userId#, #userNick#, #telPhone#, #address#, #status#,
#userType#, #remark#, now(), now())
<selectKey keyProperty="id" resultClass="java.lang.Long">
SELECT LAST_INSERT_ID() AS value
</selectKey>
</insert>
其中user表的主鍵是自增的id.
三、存在的問(wèn)題
【1-1】<selectKey keyProperty="id" resultClass="java.lang.Long">
SELECT LAST_INSERT_ID() AS value
</selectKey>
在高并發(fā)多個(gè)數(shù)據(jù)表都有寫入的情況,下,這個(gè)語(yǔ)句返回的就有可能是另外一張表剛剛寫入的記錄id,這樣根據(jù)這個(gè)id去查詢就返回沒(méi)有這個(gè)記錄了。
【1-2】解決方案:用這個(gè)user表的唯一索引user_id去重新查一次user表來(lái)獲取這個(gè)id,這種重新去查的方法基本可以滿足大部分場(chǎng)景需求