在mybatis中大批量插入数据,一般会直接使用foreach,比如:
<insertid="addItem" parameterType="java.util.List">
insertinto tableA
(
id,
name,
PID,
SORTID,
AUDIT
)
values
<foreachcollection="list" item="item" index="index"
separator=",">
(
#{item.id},
#{item.name},
#{item.permissionId},
#{item.sortId},
#{item.audit}
)
</foreach>
</insert>
但当后台传来的集合或者数组数据量比较大时,这样插入数据效率比较低。下面的写法效率相对比较高,大数据量插入速度有不小的提升:
<insertid="addItem" parameterType="java.util.List">
insertinto tableA
(
id,
name,
PID,
SORTID,
AUDIT
)
SELECT* FROM (
<foreachcollection="list" item="item" index="index"separator="UNION ALL">
SELECT
#{item.id},
#{item.name},
#{item.permissionId},
#{item.sortId},
#{item.audit}
FROMDUAL
</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
tableBwhere b0111a in(
select* from(
<foreachcollection="list" item="item" separator="UNIONALL" >
(select
#{item,jdbcType=VARCHAR}
fromdual)
</foreach>
) A)
</insert>
直接在in后面使用该语法查询,事实上,效率更低。
因此这种语法特别适合foreach中大数据量的插入。