这里面记录一下使用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的批量插入(一)的更多相关文章

  1. mybatis foreach批量插入数据:Oracle与MySQL区别

    mybatis foreach批量插入数据:Oracle与MySQL不同点: 主要不同点在于foreach标签内separator属性的设置问题: separator设置为","分 ...

  2. MyBatis原生批量插入的坑与解决方案!

    前面的文章咱们讲了 MyBatis 批量插入的 3 种方法:循环单次插入.MyBatis Plus 批量插入.MyBatis 原生批量插入,详情请点击<MyBatis 批量插入数据的 3 种方法 ...

  3. Mybatis 实现批量插入和批量删除源码实例

    Mybatis 实现批量插入数据和批量删除数据 学习内容: 准备工作 1.数据库新建表 2.新建 Maven 项目和设置编译版本及添加依赖 3.新建 db.properties 4.新建 mybati ...

  4. mybatis之批量插入

    一.导入功能优化 普通for循环,对于导入大量数据时非常耗时.可以通过Mybatis的批量插入功能提高效率.每批次导入的数据不能太多,否则会报错.通过测试发现,每批次200条为宜. 测试结果: 开启事 ...

  5. mybatis中批量插入的两种方式(高效插入)

    MyBatis简介 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用 ...

  6. MyBatis动态批量插入、更新Mysql数据库的通用实现方案

    一.业务背景 由于需要从A数据库提取大量数据同步到B系统,采用了tomikos+jta进行分布式事务管理,先将系统数据源切换到数据提供方,将需要同步的数据查询出来,然后再将系统数据源切换到数据接收方, ...

  7. 161102、MyBatis中批量插入

    方法一: <insert id="insertbatch" parameterType="java.util.List"> <selectKe ...

  8. MYSQL开发性能研究——批量插入的优化措施

    一.我们遇到了什么问题 在标准SQL里面,我们通常会写下如下的SQL insert语句. INSERT INTO TBL_TEST (id) VALUES(1);   很显然,在MYSQL中,这样的方 ...

  9. myBatis获取批量插入数据的主键id

    在myBatis中获取刚刚插入的数据的主键id是比较容易的 , 一般来说下面的一句话就可以搞定了 , 网上也有很多相关资料去查. @Options(useGeneratedKeys = true, k ...

随机推荐

  1. Scala:First Steps in Scala

    var and val 简单来说,val声明的变量可以重新修改其引用,val则不行,见下面的例子: def max(x: Int, y: Int): Int = { if(x > y) x el ...

  2. selenium之关于 chromedriver的安装和使用

    转自:https://blog.csdn.net/d77808675/article/details/79016271 最近在学习爬虫,用到了selenium 环境:Windows,python3 但 ...

  3. Linux C Socket TCP编程介绍及实例

    转自:https://blog.csdn.net/lell3538/article/details/53335231 { printf("向服务器发送数据:%s\n",sendbu ...

  4. javascript中new Date()的浏览器兼容性问题

    正确的做法: var time1 = (timestart+' 00:00:00').toString(); var time2 = (timeend+' 23:59:59').toString(); ...

  5. Mui 下拉刷新,刷新完成功能实现

    Mui中,正在刷新后,就直接回弹了,没有刷新完成这个过程,然后我就在中间添加了一个过程.   代码如下:   //-----------日期格式化------------- function form ...

  6. .Net Core AES加密解密

    一.AES说明 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替 ...

  7. Spring MVC报异常:org.springframework.web.util.NestedServletException: Request processing failed

    在使用SpringMVC绑定基本类型(如String,Integer等)参数时,应通过@RequestParam注解指定具体的参数名称,否则,当源代码在非debug模式下编译后,运行时会引发Handl ...

  8. Shell脚本编程基础笔记一

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/8176137.html 一:脚本文件的创建.格式.运行 1:创建shell脚本 首先,要创建一个文件 touch ...

  9. ado执行upadte

    /// <summary> /// 目标数据库执行ExecuteNonQuery操作 /// </summary> /// <param name="sql&q ...

  10. Swap 分区的2种方式 详解与例子

    安装完Linux系统后,swap分区太小怎么办,怎么可以扩大Swap分区呢?有两个办法,一个是从新建立swap分区,一个是增加swap分区.下面介绍这两种方法: 第一您必须有root权限,过程中一定要 ...