在mybatis中大批量插入數據,一般會直接使用foreach,比如:
<insert id="addItem" parameterType="java.util.List">
insert into tableA
(
id,
name,
PID,
SORTID,
AUDIT
)
values
<foreach collection="list" item="item" index="index"
separator=",">
(
#{item.id},
#{item.name},
#{item.permissionId},
#{item.sortId},
#{item.audit}
)
</foreach>
</insert>
但當後臺傳來的集合或者數組數據量比較大時,這樣插入數據效率比較低。下面的寫法效率相對比較高,大數據量插入速度有不小的提升:
<insert id="addItem" parameterType="java.util.List">
insert into tableA
(
id,
name,
PID,
SORTID,
AUDIT
)
SELECT * FROM (
<foreach collection="list" item="item" index="index" separator="UNION ALL">
SELECT
#{item.id},
#{item.name},
#{item.permissionId},
#{item.sortId},
#{item.audit}
FROM DUAL
</foreach>
) A
</insert>
foreach中的select將數據循環查出,其中DUAL是虛表。查出的每條數據做並集形成一張表。外層的select從這張表中查詢數據,並將查詢結果設爲臨時表A。插入的數據直接從臨時表A中獲取。
除了插入數據,查詢數據也可以使用這種語法,一般是使用sql中的in或者not in後面跟一個集合。但使用這種語法效率反而更低。代碼如下:
<insert id="copy" parameterType="java.lang.String">
INSERT INTO tableB(
id,
name,
B0111,
checked
) SELECT
REPLACE (uuid(), '-', ''),
name,
b0111a,
0
FROM
tableB where b0111a in(
select * from(
<foreach collection="list" item="item" separator="UNION ALL" >
(select
#{item,jdbcType=VARCHAR}
from dual)
</foreach>
) A)
</insert>
直接在in後面使用該語法查詢,事實上,效率更低。
因此這種語法特別適合foreach中大數據量的插入。