mysql基础---->mybatis的批量插入(一)
这里面记录一下使用mybatis处理mysql的批量插入的问题,测试有可能不准。只愿世间风景千般万般熙攘过后,字里行间,人我两忘,相对无言。
mybatis的批量插入
我们的测试主体类是springboot环境中的一个控制器类,重要的代码如下,在我们的测试中Constants.MAX_BATCH_NUMBER = 10000。
@GetMapping("insert")
public void insertBatchData() {
// 构建一个list,大小为1百万条数据
long beginCreateList = System.currentTimeMillis();
List<Map<String, Object>> lists = new ArrayList<>();
for (int i = 0; i < 100000; i ++) {
Map<String, Object> map = new HashMap<>();
map.put("userId", i + "");
map.put("username", "huhx" + i);
map.put("password", "124" + i);
map.put("sex", 1);
map.put("address", System.currentTimeMillis());
lists.add(map);
}
long endCreateList = System.currentTimeMillis();
logger.debug("创建一个大小为10万的列表,耗时:" + (endCreateList - beginCreateList)); // 4103 // 插入数据
dbSessionTemplateSupport.simpleSqlInsertBatch("user.simpleInsertUserData", lists);
long endInsertData = System.currentTimeMillis();
logger.debug("插入10万数据,耗时:" + (endInsertData - endCreateList)); //
}
一、我们每10000条数据提交一次事务
public class DbSessionTemplateSupport extends SqlSessionTemplate { public DbSessionTemplateSupport(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
} // 支持批量的插入
public void baseInsertBatch(String sqlStatement, List<Map<String, Object>> list) {
SqlSession session = getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
if (list == null || list.size() < 1) {
return;
}
int listSize = list.size();
try {
// 如果提交的列表条数小于提交阀值
if (listSize <= Constants.MAX_BATCH_NUMBER) {
for (int i = 0; i < list.size(); i++) {
session.insert(sqlStatement, list.get(i));
}
session.commit();
} else {
for (int i = 0; i < list.size(); ) {
session.insert(sqlStatement, list.get(i));
i++;
if (i % Constants.MAX_BATCH_NUMBER == 0 || i == listSize) {
session.commit();
session.clearCache();
}
}
}
} catch (Exception e) {
session.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
这种方式处理插入,仍旧比较慢(其实是很慢很慢,可能是我的代码问题,没有统计时间,太慢了)。但是这种方式可以支持oracle,下面的这种方式非常快,但是oracle不支持。
二、采用mysql支持的拼接式插入数据
/**
* mysql的批量插入方式,oracle不支持。
*
* @param sqlStatement
* @param list
*/
public void simpleSqlInsertBatch(String sqlStatement, List<Map<String, Object>> list) {
if (list == null || list.size() < 1) {
return;
}
// 如果提交的列表条数小于提交阀值
List<Map<String, Object>>[] splitLists = CommUtil.splitLists(list, Constants.MAX_BATCH_NUMBER);
for (List<Map<String, Object>> tempList : splitLists) {
insert(sqlStatement, tempList);
}
}
我们对原始的列表进行切割,然后依次的插入。每次的插入都是MAX_BATCH_NUMBER条数据。下面是切割的方法
/**
* 对一个列表按照splitNum进行分割。
*
* @param lists
* @param splitNum
* @param <T>
* @return
*/
public static <T> List<T>[] splitLists(List<T> lists, int splitNum) {
int listSize;
if (lists == null || (listSize = lists.size()) < 1) {
return new ArrayList[0];
}
int length = listSize % splitNum == 0 ? listSize / splitNum : listSize / splitNum + 1;
// 这里面如果用ArrayList,会在50行报错。ArrayList list = new List();这样会报错。
List<T>[] results = new List[length];
int fromIndex, toIndex;
for (int i = 0; i < length; i++) {
fromIndex = i * splitNum;
toIndex = (fromIndex + splitNum) > listSize ? listSize : (fromIndex + splitNum);
results[i] = lists.subList(fromIndex, toIndex);
}
return results;
}
插入的sql语句在mybatis中是使用for...each的方式,如下:
<!-- mysql的批量插入方式 -->
<insert id="simpleInsertUserData" parameterType="java.util.List">
INSERT INTO puser
(userId, username, password, address, sex)
VALUES
<foreach collection ="list" item="item" index= "index" separator =",">
(
#{item.userId},
#{item.username},
#{item.password},
#{item.address},
#{item.sex}
)
</foreach >
</insert>
10万条数据的分割时间加上插入到mysql数据库,这种方式耗时:毫秒。需要注意的是如果常数设置为10万条,也就是第10万插入一次。这种方式会报错的。
友情链接
mysql基础---->mybatis的批量插入(一)的更多相关文章
- mybatis foreach批量插入数据:Oracle与MySQL区别
mybatis foreach批量插入数据:Oracle与MySQL不同点: 主要不同点在于foreach标签内separator属性的设置问题: separator设置为","分 ...
- MyBatis原生批量插入的坑与解决方案!
前面的文章咱们讲了 MyBatis 批量插入的 3 种方法:循环单次插入.MyBatis Plus 批量插入.MyBatis 原生批量插入,详情请点击<MyBatis 批量插入数据的 3 种方法 ...
- Mybatis 实现批量插入和批量删除源码实例
Mybatis 实现批量插入数据和批量删除数据 学习内容: 准备工作 1.数据库新建表 2.新建 Maven 项目和设置编译版本及添加依赖 3.新建 db.properties 4.新建 mybati ...
- mybatis之批量插入
一.导入功能优化 普通for循环,对于导入大量数据时非常耗时.可以通过Mybatis的批量插入功能提高效率.每批次导入的数据不能太多,否则会报错.通过测试发现,每批次200条为宜. 测试结果: 开启事 ...
- mybatis中批量插入的两种方式(高效插入)
MyBatis简介 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用 ...
- MyBatis动态批量插入、更新Mysql数据库的通用实现方案
一.业务背景 由于需要从A数据库提取大量数据同步到B系统,采用了tomikos+jta进行分布式事务管理,先将系统数据源切换到数据提供方,将需要同步的数据查询出来,然后再将系统数据源切换到数据接收方, ...
- 161102、MyBatis中批量插入
方法一: <insert id="insertbatch" parameterType="java.util.List"> <selectKe ...
- MYSQL开发性能研究——批量插入的优化措施
一.我们遇到了什么问题 在标准SQL里面,我们通常会写下如下的SQL insert语句. INSERT INTO TBL_TEST (id) VALUES(1); 很显然,在MYSQL中,这样的方 ...
- myBatis获取批量插入数据的主键id
在myBatis中获取刚刚插入的数据的主键id是比较容易的 , 一般来说下面的一句话就可以搞定了 , 网上也有很多相关资料去查. @Options(useGeneratedKeys = true, k ...
随机推荐
- AngularJS中监视Scope变量以及外部调用Scope方法
在AngularJS中,有时候需要监视Scope中的某个变量,因为变量的改变会影响一些界面元素的显示.有时,也希望通过jQuery调用Scope的某个方法. 比如以下场景: <div> & ...
- mac环境下intellij的自定义配置文件位置
~/Library/Preferences/IntelliJIdea2017.2/
- OUI启动时的小错误PRVF-0002
[oracle@bys3 database]$ Starting Oracle Universal Installer... Checking Temp space: must be greater ...
- shell中函数返回值
1.前言 快半年没有写博客了,荒废了很久,工作中的杂事太多,自己越来越懒了.为了鞭策自己成长,还是要坚持写写博客,记录自己的成长. 2.shell函数介绍 语法: [ function ] funna ...
- Centos7:Failed to start LSB: Bring up/down networking
一开始配置的ifcfg-ens33 [root@cdh- ~]# cd /etc/sysconfig/network-scripts/ [root@cdh- network-scripts]# ls ...
- IDA反汇编学习
1 转自:http://www.cnblogs.com/vento/archive/2013/02/09/2909579.html IDA Pro是一款强大的反汇编软件,特有的IDA视图和交叉引用,可 ...
- 深入理解JVM(一)——JVM内存模型
JVM内存模型 Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是: 1. 程序计数器 2. Java虚拟机栈 3. 本地方法栈 4. 堆 5. 方法区. ...
- What's the difference between ConcurrentHashMap and Collections.synchronizedMap(Map)?
来自:http://stackoverflow.com/questions/510632/whats-the-difference-between-concurrenthashmap-and-coll ...
- hdoj 2594 Simpsons’ Hidden Talents 【KMP】【求串的最长公共前缀后缀】
Simpsons' Hidden Talents Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- 【Android】Android传感器
1.加速度传感器2.磁场传感器3.方向传感器4.陀螺仪传感器5.重力传感器6.线性加速度传感器7.温度传感器8.光线传感器9.距离传感器10.压力传感器11.计步传感器 首先先查看测试的安卓机拥有的传 ...