当使用Mybatis大量插入时可以利用MySQL语句的特性使原来多次请求插入的语句变成一次请求,以此提高插入效率。
一般的插入方式
//1000条数据,一条一条的插入
@Test
public void testInsert() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
long s = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
UserEntity userEntity = new UserEntity();
userEntity.setName("my name is mybatis");
userEntity.setPhone("13900000000");
userMapper.testInsert(userEntity);
System.out.println("id: " + userEntity.getId());
}
long e = System.currentTimeMillis();
System.out.println("总共耗时:" + (e - s));
}
<insert id="testInsert" useGeneratedKeys="true" keyProperty="id">
insert into t_user (name, phone)
values
(
#{name,jdbcType=VARCHAR},
#{phone,jdbcType=VARCHAR}
)
</insert>
优化后的批量插入方式
@Test
public void testBatchInsert() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<UserEntity> userEntityList = new ArrayList<>();
long s = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
UserEntity userEntity = new UserEntity();
userEntity.setName("my name is mybatis");
userEntity.setPhone("13900000000");
userEntityList.add(userEntity);
}
userMapper.testBatchInsert(userEntityList);
for (UserEntity userEntity : userEntityList) {
System.out.println("id: " + userEntity.getId());
}
long e = System.currentTimeMillis();
System.out.println("总共耗时:" + (e - s));
}
<insert id="testBatchInsert" useGeneratedKeys="true" keyProperty="id">
insert into t_user (name, phone)
values
<foreach collection="list" separator="," item="user">
(
#{user.name,jdbcType=VARCHAR},
#{user.phone,jdbcType=VARCHAR}
)
</foreach>
</insert>
两种方式都实现了插入语句,并且都能拿到返回值,但是普通的方式才插入1000条数据就要耗时20几秒,而优化后的插入方式则1秒都不到,并且随着插入的数据量不断增多,性能对比会更加悬殊。