美文网首页
(5) 批量操作

(5) 批量操作

作者: Mrsunup | 来源:发表于2018-10-28 20:57 被阅读0次

    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 循环插入
     /**
         * 方式一: 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>
    
    • 拼装insert 的SQL语句
    @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>
    
    • batch批量插入

    注意批量插入的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
        }
    
    • 更多的配置细节
      参考github的项目mybatis下的mybatis-generator工程下的com.mybatis.bestPractice.batch

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

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

    相关文章

      网友评论

          本文标题:(5) 批量操作

          本文链接:https://www.haomeiwen.com/subject/xipmtqtx.html