美文网首页
mybati批量插入数据比较

mybati批量插入数据比较

作者: b470b9fc7145 | 来源:发表于2017-12-27 16:33 被阅读250次

运行demo之前一定要自己去本地mysql建表

前言

此时比较的四插入1W条数据,本地mysql数据库,分别数是

  1. 一条一条插入
  2. 批量一起插入
  3. mybatis自带的batch

结果

  1. 耗时50s+
  2. 耗时5s+
  3. 耗时10+

用到的java代码/mapper/表结构

  1. java代码
/**
 * 
 */
package com.cbw.service;

import java.sql.SQLException;
import java.util.ArrayList;

import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.cbw.TestMavenApplication;
import com.cbw.model.pojo.TTScore;

/**
 * @Title: TestScoreService.java
 * @Package com.cbw.service
 * @Description: TODO(用一句话描述该文件做什么)
 * @author cbw
 * @date 2017年12月27日 下午3:36:33
 * @version V1.0
 */

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestMavenApplication.class)
public class TestScoreService {

    @Autowired
    private ScoreService scoreService;
    
    @Autowired  
    private SqlSessionTemplate sqlSessionTemplate;  

    /**
     * 测试查询数据
     * 
     * @throws Exception
     */
    @Test
    public void testService() throws Exception {

        System.out.println("scoreService----的结果.....");
        System.out.println(scoreService);

        TTScore ttscore = scoreService.selectByPrimaryKey(1);

        System.out.println(ttscore);

    }

    /**
     * 测试批量插入数据 耗时51s
     * 
     * @throws Exception
     */
    @Test
    public void testInsertBatch() throws Exception {

        for (int i = 0; i < 10000; i++) {

            TTScore score = new TTScore();
            score.setCid(10000 + i);
            score.setName("name" + "-" + i);
            System.out.println("开始插入....");
            scoreService.insert(score);
            System.out.println("开始插入结束....");
        }
    }

    /**
     * 使用foreach,5s(最快)
     * 
     * @throws Exception
     */
    @Test
    public void testInsertBatch2() throws Exception {

        ArrayList<TTScore> list = new ArrayList<TTScore>();

        for (int i = 0; i < 10000; i++) {
            TTScore score = new TTScore();
            score.setCid(20000 + i);
            score.setName("name" + "-" + i);
            list.add(score);
        }

        System.out.println("开始插入数据...");
        scoreService.insertBatch(list);
        System.out.println("插入数据结束...");
    }
    
    /**
     * 使用mabatis自带的batch进行插入,耗时(10)中等
     * @throws SQLException 
     */
    @Test
    public void testInsertBatchByTrue() throws SQLException {  
           
        //新获取一个模式为BATCH,自动提交为false的session  
        //如果自动提交设置为true,将无法控制提交的条数,改为最后统一提交,可能导致内存溢出  
        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);  
        //通过新的session获取mapper  
            session.getConnection().setAutoCommit(false);//不自动提交  
//          fooMapper = session.getMapper(TTScoreMapper.class);  
            int size = 10000;  
            try {  
                for (int i = 0; i < size; i++) {  
                        TTScore score = new TTScore();  
                        score.setCid(10000 + i);
                        score.setName(String.valueOf(System.currentTimeMillis())); 
                        
                        scoreService.insert(score);
                            if (i % 1000 == 0 || i == size - 1) {  
                            //手动每1000个一提交,提交后无法回滚  
                            session.commit();  
                            //清理缓存,防止溢出  
                            session.clearCache();  
                          }  
                }  
            } catch (Exception e) {  
                //没有提交的数据可以回滚  
                                session.rollback();  
                    } finally {  
                session.close();  
                }  
            }  

}

  1. 数据库表的结构
Create Table

CREATE TABLE `tt_score` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `kecheng` varchar(50) DEFAULT NULL,
  `fenshu` int(11) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=20000 DEFAULT CHARSET=utf8

foreach标签讲解

对于foreach标签的解释参考了网上的资料,具体如下:

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。

foreach元素的属性主要有 item,index,collection,open,separator,close。

item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔 符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况:

1.如果传入的是单参数且参数类型是一个List的时候,collection属性值为list

2.如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array

3.如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map

demo地址

demo

参考资料

mybatis批量插入数据
Mybatis 大数据量的批量insert解决方案
spring boot写单元测试(测试service层)

相关文章

网友评论

      本文标题:mybati批量插入数据比较

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