1. 使用循环进行插入
void insertUserByLoop() {
// 生成数据
List<User> users = generateData();
// 循环插入
for (User user : users) {
mybatisDemoMapper.insertUser(user);
}
}
使用这种方式进行大数据量插入的效率最低,因为每次执行SQL都需要创建一个新的SqlSession,并生成PreparedStatement对象,执行完之后再关闭SqlSession。
这种方式适合少量数据的插入。
2. 使用foreach标签进行插入
mapper.xml文件可以这么写:
<insert id="insertUsers">
insert into mybatis_demo.user values
<foreach collection="users" item="user" separator=",">
<if test="user.id != null and user.id != ''">
(
#{user.id},
#{user.username},
#{user.password}
)
</if>
</foreach>
</insert>
这种方式会形成一个特别大的SQL,其生成的PreparedStatement中占位符会相当多,解析起来比较费时;同时 Mysql 对执行的SQL语句大小也有限制,默认允许最大4M,若SQL过长,执行也会抛出异常。
这种方式一般适合100行以内的批量插入。
3. 使用批处理进行插入
void insertUserByBatch() {
List<User> users = generateData();
// 批处理方式,关闭自动提交
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
MybatisDemoMapper mapper = sqlSession.getMapper(MybatisDemoMapper.class);
for (int i = 0; i < users.size(); i++) {
mapper.insertUser(users.get(i));
// 每1000条数据提交一次
if ((i + 1) % BATCH_SIZE == 0) {
sqlSession.commit();
}
}
sqlSession.commit();
}
这种方式仅生成一个PreparedStatement,数据库等待需要运行的参数,接收到参数后一次运行,一般来说可以分多次进行批量提交。
这种方式适合大数据量的插入。