Mybatis批量插入注解方式示例(oracle + mysql)

版权声明:转载请注明出处哦 https://blog.csdn.net/k99sam/article/details/82253488

场景:

导入20万条数据,for循环方式一条条插入巨慢(太low)。拼接长SQL的话,oracle根本无法支持(有SQL长度限制),经测试数据多于2000基本就不行了。故改用批量插入,在mapper中注解使用mybatis的foreach标签写。Mybatis框架会自动拼接生成批插的sql。


mysql版(这里只写2个字段,大家自己照葫芦画瓢)

    @Insert(
            {   "<script>",
                    "insert into users ",
                    "(USERNAME,PASSWORD) ",
                    "VALUES",
                    "<foreach collection ='list' item='ulist' separator =','>",
                    "(#{ulist.username},#{ulist.password})",
                    "</foreach> ",
                "</script>"
            }
    )

    public void batch_insert(List<UserEntity> userList);

要点解析:

1. 注解的{} 中,长的SQL要换行的话,注意逗号和引号,每行内容在" "中。({}中内容是数组,这个好理解)

2. <foreach>标签中是循环拼接的语句,注意前后有(),字段务必在括号里

3. collection ='list'  标明传入的数据是list类型的(还有其他的,请参阅官方文档)

4. item值不必与形参名字相同,它的作用可以这么理解:形参的替身/别名,如下图:

5. separator =','  说明要用什么来分隔两段语句(可以看oracle的例子,这里有什么不同)

最终拼接出来的语句如下(如果插入2行数据):

insert into users (username,password) values ('sam','123'),('tom','456');

oracle版:

    @Insert(
         {"<script>",
            "insert into users ",
            "(ID,username,password) ",
            "SELECT SEQ_USERS.NEXTVAL, A.* FROM (",
            "<foreach collection ='list' item='ulist' separator ='union all'>",
            "(SELECT #{ulist.username},#{ulist.password} FROM DUAL)",
            "</foreach> ) A",
            "</script>"
         }
    )

    public void batch_insert(List<UserEntity> userList);

比较复杂,使用了嵌套结构,多行语句之间使用union all连接。

特别注意,如果要插入序列,序列是要写在foreach外的。


实际运行测试:

使用oracle,每批2000条commit一次为最佳。

换用mysql,可以20000条再commit一次,且速度比oracle快多了(同一台机器测试)。

猜你喜欢

转载自blog.csdn.net/k99sam/article/details/82253488