相信很多人都遇到过往Mybatis的Mapper.xml文件粘贴SQL的时候,因为多了一个’;’而导致SQL报错的情形吧。
难道就不能执行多条SQL了么?其实是可以的。在分表的情况下,这种需求是强烈的,比如在大批量插入数据的情形下,同时为了达到数据与表名之间的关系能够相互推算,必须实现不同数据插入不同的表,最简单的实现就是,通过数据计算Table ID,然后根据Table ID插入不同的表,程序内部做循环,但如果数据量达到百万或者千万级别,这种性能是让人无法忍受的。类似下面的SQL
insert into Table_Name_${tableId}
(
XXX1,
XXX2,
XXX3
)
VALUES
(
#{xxx1,jdbcType=BIGINT},
#{xxx2,jdbcType=BIGINT},
#{xxx3,jdbcType=BIGINT}
)
单条和List批量插入,性能相差到底多少?网上也有测试,有的说只有几倍,但我的个人项目而言,性能差距是几十倍。用传统MyBatis,单条插入1000条数据,需要30秒,但如果批量的话,插入速度大概是1秒2000-3000条,批量插入的性能比单条插入的性能提升了整整60-100倍。
废话那么多,怎么实现呢?首先,你需要配置你的jdbc url,加入如下参数(其它参数已经省略,我使用的连接池是druid)。
jdbc:mysql://127.0.0.1:3306/xxx?allowMultiQueries=true
然后,在Mapper.xml里面,就能够欢快的用如下SQL实现多表动态插入了
<insert id="insertXXXs" parameterType="java.util.List" useGeneratedKeys="true" >
<foreach collection="list" item="item" index="index" separator=";">
insert into TABLE_NAME_${item.tableId}
(
XXX1,
XXX2,
XXX3
)
VALUES
(
#{item.xxx1,jdbcType=BIGINT},
#{item.xxx2,jdbcType=BIGINT},
#{item.xxx3,jdbcType=BIGINT},
)
</foreach>
</insert>
当然了,肯定不止是插入,其它操作依然适用。