mybatis三种批量插入方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014714713/article/details/82193237

普通for循环插入

public void testInsertBatch2() throws Exception {
    User user;
    SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(false);
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    for (int i = 0; i < 500; i++) {
        user = new User();
        user.setId("test" + i);
        user.setName("name" + i);
        user.setDelFlag("0");
        mapper.insert(user);
    }
    sqlSession.commit();
}
<insert id="insert">
    INSERT INTO t_user (id, name, del_flag)
          VALUES(#{id}, #{name}, #{delFlag})
</insert>

BATCH模式插入

@Test
public void testInsertBatch2() throws Exception {
    User user;
    SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    for (int i = 0; i < 500; i++) {
        user = new User();
        user.setId("test" + i);
        user.setName("name" + i);
        user.setDelFlag("0");
        mapper.insert(user);
    }
    sqlSession.commit();
}
<insert id="insert">
    INSERT INTO t_user (id, name, del_flag)
          VALUES(#{id}, #{name}, #{delFlag})
</insert>

ExecutorType

Mybatis内置的ExecutorType有3种,默认的是ExecutorType.SIMPLE,该模式下它为每个语句的执行创建一个新的预处理语句,单条提交sql;其次是ExecutorType.REUSE,该模式下将将重复使用预处理语句PreparedStatement;而ExecutorType.BATCH,该模式下重复使用已经预处理的语句,
并且批量执行所有更新语句,显然batch性能将更优;

缺点

在同一事务中batch模式和simple模式之间无法转换。
SqlSession的执行器类型一旦设置就无法动态修改,所以如果在配置文件中设置了执行器为SIMPLE,当要使用BATCH执行器时,需要临时获取。

foreach方式插入

@Test
public void testInsertBatch() throws Exception {
    List<User> list = new ArrayList<>();
    User user;
    for (int i = 0; i < 10000; i++) {
        user = new User();
        user.setId("test" + i);
        user.setName("name" + i);
        user.setDelFlag("0");
        list.add(user);
    }
    userService.insertBatch(list);
}

拼接SQL语句

<insert id="insertBatch">
    INSERT INTO t_user
            (id, name, del_flag)
    VALUES
    <foreach collection ="list" item="user" separator =",">
         (#{user.id}, #{user.name}, #{user.delFlag})
    </foreach >
</insert>

上述SQL语句有一个弊病,那就是插入的数据超过千条后,就提示插入不成功,因为一条Insert语句插入的数据量是不能超过一千条的。

可以使用union all拼接

<insert id="insertBatch">
    INSERT INTO t_user
            (id, name, del_flag)
    VALUES
    <foreach collection ="list" item="user" open="(" close=")" separator ="union all">
         #{user.id}, #{user.name}, #{user.delFlag}
    </foreach >
</insert>

或者多条insert语句

<insert id="insertBatch">
    <foreach collection ="list" item="user" >
         INSERT INTO t_user
            (id, name, del_flag)
        VALUES
            (#{user.id}, #{user.name}, #{user.delFlag})
    </foreach >
</insert>

mysql默认接受sql的大小是1048576(1M),即第三种方式若数据量超过1M会报如下异常:(可通过调整MySQL安装目录下的my.ini文件中[mysqld]段的"max_allowed_packet = 1M")

猜你喜欢

转载自blog.csdn.net/u014714713/article/details/82193237