mybatis三種批量插入方式
阿新 • • 發佈:2019-02-06
普通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")