Mybatis批量插入3种方式!同事看完直呼好家伙

前言

数据库使用的mysql,jdk版本1.8,springboot环境,   需要注意的是我们测试的单条sql比较短

max_allowed_packet指代mysql服务器端和客户端在一次传送数据包的过程当中最大允许的数据包大小。这里是4M

对比以下三种方式:

  1. for循环执行单条插入语句
  2. xml拼接sql
  3. 批处理执行

代码

mapper

@Mapper
public interface UserMapper {

    int insert(User user);

    int insertByBatch(List<User> users);

    int delete();
}

xml

  <insert id="insert" parameterType="com.example.mybatisdemo.entity.User">
        insert into user (name,age) values(#{name},#{age});
    </insert>

    <insert id="insertByBatch" parameterType="java.util.List">
        insert into user (name,age) values
        <foreach collection="list" item="item" separator=",">
            (#{item.name},#{item.age})
        </foreach>
    </insert>

    <delete id="delete">
        delete from user
    </delete>

拼接方式需要注意如果使用的是Oracle 

<foreach collection="list" item="item"  separator ="UNION ALL">
</foreach>

测试类

@SpringBootTest
class MybatisdemoApplicationTests {

    @Autowired
    UserMapper userMapper;

    @Autowired
    SqlSessionFactory sqlSessionFactory;

    private List<User> users = new ArrayList<User>();

    @Test
    void delete(){
        userMapper.delete();
    }

    @Test
    void insert() {
        for (int i = 0; i < 1000; i++){
            User user = new User();
            user.setName("人物"+i);
            user.setAge(i);
            users.add(user);
        }
        long start = System.currentTimeMillis();
        users.forEach(userMapper::insert);
        System.out.println(System.currentTimeMillis() - start);
    }

    @Test
    void insertByBatch(){
        for (int i = 0; i < 1000; i++){
            User user = new User();
            user.setName("人物"+i);
            user.setAge(i);
            users.add(user);
        }
        long start = System.currentTimeMillis();
        userMapper.insertByBatch(users);
        System.out.println(System.currentTimeMillis() - start);
    }

    @Test
    void insertByOnce(){
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        long start = 0L;
        for (int i = 0; i < 1000; i++){
            User user = new User();
            user.setName("人物"+i);
            user.setAge(i);
            start = System.currentTimeMillis();
            mapper.insert(user);
            if (i%1000 == 999){
                //每1000条提交一次防止内存溢出
                sqlSession.commit();
                sqlSession.clearCache();
            }
        }
//        sqlSession.commit();
//        sqlSession.clearCache();
        System.out.println(System.currentTimeMillis() - start);
    }
}

对比

方式 50条 1000条 2000条 3000条
for循环 562ms 2577ms 4828ms 6144ms
xml拼接 479ms 582ms 618ms 655ms
批处理 75ms 1683ms 1790ms 1843ms

注意我们这里测试的单条sql较短,当xml拼接过长就会报以下错误

总结

循环插入单条数据  效率确实不好,但是代码量少,在需求插入数据量不大的情况也是可以使用的。

xml拼接sql方式   网上千篇一律的说任何时候都不要使用,但是我觉得在可控范围内,效率这么好为什么不使用呢,当然必须要注意上面报错的情况,还是根据实际情况而定。

批处理执行 有大量数据插入时推荐此方式。

猜你喜欢

转载自blog.csdn.net/QingXu1234/article/details/115265185
今日推荐