1. 程式人生 > >mybatis三種批量插入方式

mybatis三種批量插入方式

普通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")