(5) 批量操作

2018-10-28  本文已影响0人  Mrsunup

1.常用的批量插入的方式

下面的图表展示了mybatis几种方式的批量插入

方式 性能 说明
for 循环 一个一个插入 低,每次都要IO 普通插入
拼装SQL(性能最高、推荐使用) 有 SQL 长度限制,定好 List 大小,可以通过下面的语句查询数据包的限制的大小:show variables like '%packet%';show variables like '%net_buffer%';
批量插入 需要通过sqlSession开启批量插入, SqlSession sqlSession =sqlSessionFactory.openSession(ExecutorType.BATCH, false);

2.批量插入的测试

@Before
    public void setUp() throws Exception {
        //创建sqlsessionFactory
        String resource = "SqlMapConfig.xml";
        //得到配置文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //创建会话工厂,传入mybatis的配置文件的信息
        sqlSessionFactory  = new SqlSessionFactoryBuilder().build(inputStream);
    }
 /**
     * 方式一: for 循环 一个一个插入
     * @throws Exception
     */
    @Test
    public void batchInsertTest() throws  Exception{
        long start = System.currentTimeMillis();
        SqlSession sqlSession  =sqlSessionFactory.openSession();
        //创建userMapper对象,mybatis自动生成mapper代理对象
         UserMapper userMapper =  sqlSession.getMapper(UserMapper.class);
        for (int i = 0; i < 100; i++) {
            User  user= new User();
            user.setSex("男");
            user.setUsername("sun");
            user.setAddress("address");
            userMapper.insert(user);
        }
        sqlSession.commit();
        log.info("cost {}ms", System.currentTimeMillis() - start);
        //输出日志如下: INFO [main] - cost 1928ms
    }

对应的mapper的xml的内容

  <insert id="insert" parameterType="com.mybatis.project.po.User">
    insert into user (id, username, birthday, 
      sex, address)
    values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{birthday,jdbcType=DATE}, 
      #{sex,jdbcType=CHAR}, #{address,jdbcType=VARCHAR})
  </insert>
@Test
    public void insertBatchByConnSql() {
        long start = System.currentTimeMillis();
        SqlSession sqlSession  =sqlSessionFactory.openSession();
        //创建userMapper对象,mybatis自动生成mapper代理对象
         UserMapper userMapper =  sqlSession.getMapper(UserMapper.class);
         List<User> userList = new ArrayList<User>();
        for (int i = 0; i < 100; i++) {
            User  user= new User();
            user.setSex("男");
            user.setUsername("sun");
            user.setAddress("address");
            userList.add(user);
        }
        userMapper.insertBatch(userList);
        sqlSession.commit();
        log.info("cost {}ms", System.currentTimeMillis() - start);
        // INFO [main] - cost 1610ms
    }

对应的insertBatch方法中的mapper的xml文件的内容如下:

  <insert id="insertBatch" parameterType="list">
    insert into user(username,birthday,sex,address) values
    <foreach collection="list" item="user"  separator=",">
      (#{user.username},#{user.birthday},#{user.sex},#{user.address})
    </foreach>
  </insert>

注意批量插入的openSession的方法指定了ExecutorType的类型为批量插入,然后事务的自动提交设置为false

如果感兴趣的,可以参考原生的jdbc的批量更新 的方式,可以参考:https://www.jianshu.com/p/c5d7da273c8d的批量更新的章节的内容

//方式三: 执行批量插入,10个一插入
    @Test
    public void insertBatchByConnectSql() {
        long start = System.currentTimeMillis();
        SqlSession sqlSession  =sqlSessionFactory.openSession(ExecutorType.BATCH, false);
        //创建userMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper =  sqlSession.getMapper(UserMapper.class);
        List<User> userList = new ArrayList<User>();
        for (int i = 0; i < 100; i++) {
            User  user= new User();
            user.setSex("男");
            user.setUsername("sun");
            user.setAddress("address");
            userMapper.insert(user);
            if (i % 10 == 0 && i != 0) {
                sqlSession.commit();
                sqlSession.clearCache();
            }
        }
        log.info("cost {}ms", System.currentTimeMillis() - start);
        //输出日志如下:INFO [main] - cost 1673ms
    }

地址为: https://github.com/sunkang123/mybatis

总结:可以通过输出的日志发现,每个批量插入的我都加入了执行时间的日志,发现了最短的执行情况为方式二:通过拼装sql的方式,要考虑性能的话,推荐使用拼装的sql,方式二和方式三的区别在于,方式二是一次性发送一个可执行的sql,方式三是一次方式发送多个可执行的sql

上一篇下一篇

猜你喜欢

热点阅读