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 ...
随机推荐
- verilog语法实例学习(12)
verilog中的综合和不可综合总结 Verilog中综合的概念 综合就是EDA工具或者说综合工具把我们编写的verilog代码转化成具体电路的过程.Verilog中有很多语法,结构,过程,语句,有些 ...
- 关于three.js中添加文字的方式[转]
https://blog.csdn.net/qq563969790/article/details/76584976 网上资料大部分是通过引入外部font库进行文字效果的载入,但是在实际运行的时候发现 ...
- web打印控件Lodop轻松输出清晰的图表和条码
一.仅用两行语句实现极其复杂的图表打印.类似如下两句: LODOP.ADD_PRINT_CHART(0,0,400,400,5,document.getElementByI d('table001') ...
- 腾讯云SpringBoot部署 + HTTPS配置
springboot可以打包为jar和war,jar不多说了,最近的一个工程需要打包为war发布,大致说一下吧: 先看一下项目的大致结构: 第一步,需要排除springboot自带的tomcat插件 ...
- 译:2. RabbitMQ Java Client 之 Work Queues (工作队列)
在上篇揭开RabbitMQ的神秘面纱一文中,我们编写了程序来发送和接收来自命名队列的消息. 本篇我们将创建一个工作队列,工作队列背后的假设是每个任务都交付给一个工作者 本篇是译文,英文原文请移步:ht ...
- CSA Enterprise Architecture图
https://research.cloudsecurityalliance.org/tci/index.php/explore/
- FOR XML PATH 可以将查询结果根据行输出成XML格式
SELECT CAST(OrderID AS varchar)+',' as OrderNo FROM Product CAST函数用于将某种数据类型的表达式显式转换为另一种数据类型 SELECT C ...
- Multiplication of numbers
Questin: There is an array A[N] of N numbers. You have to compose an array Output[N] such that Outpu ...
- 【Android】开源项目UniversalImageLoader及开源框架ImageLoader
UniversalImageLoader 简单来说就是用于加载图片的一个开源项目,在其项目介绍中是这么写的 支持多线程图片加载 提供丰富的细节配置,比如线程池大小,HTPP请求项,内存和磁盘缓存,图片 ...
- 【iCore1S 双核心板_ARM】例程十四:FATFS实验——读写文件
实验现象: 核心代码: int main(void) { /* USER CODE BEGIN 1 */ int i; int j; FIL file; FATFS fatfs; //Âß¼Çý¶¯ ...