Mybatis批量insert 返回主鍵
Mybatis從3.3.1版本開始,支持批量插入后返回主鍵ID。首先對於支持自增主鍵的數據庫使用useGenerateKeys和keyProperty,對於不支持生成自增主鍵的數據庫使用selectKey標簽。類似《MyBatis 返回insert操作主鍵》中單條插入。
使用批量插入,可以減少和數據庫交互的次數,但是,數據量應該做一個控制,和for循環類似。首先定義Java Bean Instance:
import java.io.Serializable;
/** * 實例表實體類 */ public class Instance implements Serializable { private static final long serialVersionUID = 2288066394131442938L;
private Long instanceId; private String infos; private String createTime; private String updateTime; // omit getter, setter and toString() } |
DAO層:
int addInstances(List<Instance> instanceDtos); |
函數返回值是int類型,表示影響的行數。mapper中SQL寫法類似於執行單條insert操作,只是使用了foreach標簽:
<insert id="addInstances" parameterType="list" useGeneratedKeys="true" keyProperty="instanceId"> insert into instance (infos,create_time,update_time) values <foreach collection="list" item="myEg" index="index" separator=","> (#{myEg.infos},now(),now()) </foreach> </insert> |
執行后,自增長的id都可以從instanceDtos中找到。由於myEg對應於Java對象,所以,讀取其中的infos屬性時,需要使用myEg.infos。
MyBatis foreach標簽詳解
下面梳理一下foreach標簽。foreach主要用於構建in條件,它可以在SQL語句中迭代入參List或者Array。屬性主要有 item,index,collection,open,separator,close,解釋如下:
item表示集合中每一個元素進行迭代時的別名,便於在foreach中使用;
index指定一個名字,用於標志當前迭代位置;
open表示該語句以什么開始,如拼湊in子語句的左括號“(”;
separator分隔符,表示每次迭代之間以什么符號分隔;
close表示以什么結束,如拼湊in子語句的右括號“)”。
在所有屬性中,最復雜非collection屬性莫屬,該屬性在foreach標簽中必須指定的。在不同情況下,該屬性的值是不一樣的,主要有以下3種情況:
1.若傳入的是單參數且參數類型是List,則collection屬性值為list;
2.若傳入的是單參數且參數類型是Array數組,則collection的屬性值為array;
3.若傳入的參數是多個,則把它們封裝成Map,當然單參數也可以封裝成Map,collection的屬性值為Map中的key;
上一節中,addInstances函數的入參只有一個,且是List,所以,collection屬性值為list。如下函數
List<Instance> getInstanceInfo(new Long[]{1L, 3L}); |
請求的時候,SQL如下:
<select id="getInstanceInfo" resultType="list"> SELECT instance_id "instanceId", infos FROM instance WHERE instance_id IN <foreach item="oneId" index="index" collection="array" open="(" separator="," close=")" > #{oneId} </foreach> </select> |
oneId表示一個具體的元素,所以,用#{oneId}直接讀取就行。