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 ...
随机推荐
- WinForm EF+MySql企业管理软件C/S项目实战演练
一.课程介绍 我们都知道在软件架构方式分为:C/S和B/S两类.这里阿笨不谈论两种软件架构的优劣之分,因为它们各有千秋,用于不同场合.一位伟大的讲师曾经说过一句话:事物存在即合理!录制这堂课程的目的就 ...
- 八幅漫画理解使用 JSON Web Token 设计单点登录系统
原文出处: John Wu 上次在<JSON Web Token – 在Web应用间安全地传递信息>中我提到了JSON Web Token可以用来设计单点登录系统.我尝试用八幅漫画先让大家 ...
- 【FFmpeg】ffplay播放rtsp视频流花屏问题 (转)
问题描述:ffplay播放rtsp视频流时,播放过程中随机出现花屏现象. 基本流程学习:阅读ffplay源码,熟悉其播放rtsp视频流的基本流程. 在ffplay源码阅读和分析的基础上,画出了其播放r ...
- WIN10平板 总是提示你需要管理员权限怎么办
例如在往C盘拷贝文件的时候,会出现下面的提示,虽然点击继续也可以执行,但是还是非常麻烦 WIN+R,打开组策略 在Windows设置-安全设置-安全选项中,找到用户账户控制,设置为已禁用,应用 ...
- Web 安全 之 OpenSSL
什么是OpenSSL协议? SSL(Secure SocketLayer,安全套接层)协议是使用最为普遍网站加密技术,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技 ...
- Windows视频桌面壁纸实现(libvlc)(类似于wall paper engine效果)
简介 这个项目是很久之前的事情了,当时一个朋友正在研究一个国外的软件(wall paper engine ),可以在桌面壁纸层播放视频,也就差不多是动态壁纸的意思. 后来我也动手来实现这个功能,因为手 ...
- phpBB3.2开发环境配置
从Github导出项目 如果只是查看代码, 可以直接clone官方的git https://github.com/phpbb/phpbb.git . 如果需要开发, 就fork一下再从自己的Git里c ...
- 在 OC 中调用 Swift 代码
1.在 Objective-C 项目中使用 Swift 代码 1)在 OC 项目中创建 .Swift 文件,文件中的格式为其本有的格式. 2)Xcode 提示是否创建 Objective-C brid ...
- android用TextView实现跑马灯效果
今天搞啦很久,其实很简单,就加几个属性就可以啦! 图如下 : 有的说要重写TextView方法,有的说要设置固定长度,但是我没重写也没有设置固定长度也弄出来啦!跑在2.3.3的手机上面.就是不知道其他 ...
- Cortex-A15架构解析:它为什么这么强(转)
今年的新手机趋势无异是全面向四核靠拢,不过同样是四核,在实际的性能上其实是千差万别.例如针对入门级主流市场的四核手机普遍采用的都是Cortex-A7以及 Cortex-A9 级别的CPU内核,这类内核 ...