一、關於 mybatis foreach標籤
mybatis中foreach的主要用在構建in條件中,它可以在SQL語句中進行迭代一個集合。
foreach標籤的屬性主要有 item,index,collection,open,separator,close。
item表示集合中每一個元素進行迭代時的別名,index指定一個名字,用於表示在迭代過程中,每次迭代到的位置,open表示該語句以什麼開始,separator表示在每次進行迭代之間以什麼符號作爲分隔 符,close表示以什麼結束,在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,但是在不同情況 下,該屬性的值是不一樣的,主要有一下3種情況:
- 如果傳入的是單參數且參數類型是一個List的時候,collection屬性值爲list
- 如果傳入的是單參數且參數類型是一個array數組的時候,collection的屬性值爲array
- 如果傳入的參數是多個的時候,我們就需要把它們封裝成一個Map了,當然單參數也可以封裝成map
使用批量插入執行的SQL語句應該等價於:
insert into redeem_code (batch_id, code, type, facevalue,create_user,create_time)
values
(?,?,?,?,?,? ),(?,?,?,?,?,? ),(?,?,?,?,?,? ),(?,?,?,?,?,? )
二、oracle和mysql中使用foreach的不同
Mybatis使用foreach批量插入的時候,針對不同的數據庫,寫法也是不一樣的,很多習慣了mysql寫法的同學,在換庫到oracle的時候會踩到這些坑。
主要不同點在於foreach標籤內separator屬性的設置問題:
- mysql:separator設置爲","分割時,最終拼接的代碼形式爲:insert into table_name (a,b,c) values (v1,v2,v3) ,(v4,v5,v6) ,...
- oracle:separator設置爲"union all"分割時,最終拼接的代碼形式爲:insert into table_name (a,b,c) values (v1,v2,v3) union all (v4,v5,v6) union all...
代碼如下,
1、mysql
separator設置爲","分割,
<insert id="insertBatchUser" parameterType="com.test.User">
insert into table_name (name, adress, age)
values
<foreach collection="list" item="item" index="index" separator=",">
( #{item.name}, #{item.adress}, #{item.age} )
</foreach>
</insert>
2、oracle
separator設置爲"union all"分割,並且參數使用 select .... from dual
<insert id="insertBatchUser" parameterType="com.test.User">
insert into table_name (name, adress, age)
values
<foreach collection="list" item="item" index="index" separator="union all">
(select #{item.name},
#{item.adress},
#{item.age}
from dual )
</foreach>
</insert>