运行demo之前一定要自己去本地mysql建表
前言
此时比较的四插入1W条数据,本地mysql数据库,分别数是
- 一条一条插入
- 批量一起插入
- mybatis自带的batch
结果
- 耗时50s+
- 耗时5s+
- 耗时10+
用到的java代码/mapper/表结构
- 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();
}
}
}
- 数据库表的结构
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地址
参考资料
mybatis批量插入数据
Mybatis 大数据量的批量insert解决方案
spring boot写单元测试(测试service层)
网友评论