Mybatis批量插入返回插入成功後的主鍵id
我們都知道Mybatis在插入單條資料的時候有兩種方式返回自增主鍵:
1、對於支援生成自增主鍵的資料庫:增加 useGenerateKeys和keyProperty ,<insert>標籤屬性。
2、不支援生成自增主鍵的資料庫:使用<selectKey>。
但是怎麼對批量插入資料返回自增主鍵的解決方式網上看到的還是比較少,至少百度的結果比較少。
Mybatis官網資料提供如下:
First, if your database supports auto-generated key fields (e.g. MySQL and SQL Server), then you can simply set useGeneratedKeys="true"
<insertid="insertAuthor"useGeneratedKeys="true"keyProperty="id"> insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio})</insert>
If your database also supports multi-row insert, you can pass a list or an array of Authors and retrieve the auto-generated keys.
<insertid="insertAuthor"useGeneratedKeys="true"keyProperty="id"> insert into Author (username, password, email, bio) values <foreachitem="item"collection="list"separator=","> (#{item.username}, #{item.password}, #{item.email}, #{item.bio}) </foreach></insert>
從官網資料可以看出Mybatis是支援批量插入時返回自增主鍵的。
但是在本地測試的時候使用上述方式確實不能返回自增id,而且還報錯(不認識keyProperty中指定的Id屬性),然後在網上找相關資料。終於在Stackoverflow上面找到了一些資訊。
解決辦法:
1、升級Mybatis版本到3.3.1。官方在這個版本中加入了批量新增返回主鍵id的功能
2、在Dao中不能使用@param註解。
3、Mapper.xml中使用list變數(parameterType="java.util.List")接受Dao中的引數集合。
下面是具體程式碼過程,可供參考
mapper.xml層程式碼
<!-- 批量新增 -->
<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO
<include refid="t_shop_resource" />
(relation_id, summary_id, relation_type)
VALUES
<foreach collection="list" index="index" item="shopResource" separator=",">
(
#{shopResource.relationId}, #{shopResource.summaryId}, #{shopResource.relationType}
)
</foreach>
</insert>
dao實現層程式碼
public List<ShopResource> batchinsertCallId(List<ShopResource> shopResourceList)
{
this.getSqlSession().insert(getStatement(SQL_BATCH_INSERT_CALL_ID), shopResourceList);
return shopResourceList;// 重點介紹
}
為什麼最後返回的引數不是挑用mybatis後的insert的返回值呢,細心的話可以發現,如果使用debug模式觀察,會看到呼叫mybatis後insert的返回值是[],也就是空集合元素,在mybatis3.3.1中,雖然加入了批量新增返回主鍵id的功能,但是它是這樣執行的,在需要新增插入新元素集合物件時,它會需要引數物件,當執行完插入操作後,給之前的引數物件設定id值,也就是改變了需要插入物件集合中的元素的屬性id值, 所以接收返回時,返回方法形參引數即可,同樣的地址引用改變了內容,返回後的集合也是改變後的集合。
參考地址: