批量插入有三个问题,第一是执行效率,第二数据冲突,第三数据重跑更新操作。

一般对于这样的问题有以下操作方法。

第一是执行效率:mybatis支持两种高效插入。

1.mybtis的foreach标签,foreach元素的属性主要有 item,index,collection,open,separator,close。

通过迭代把对应元素的属性批量插入。

<insert id="batchInsert">
insert into day_time(daily_year,daily_month,daily_week,daily_date,use_num,types)
values
<foreach collection="list" item="item" separator=",">
(#{item.dailyYear},#{item.dailyMonth},#{item.dailyWeek},#{item.dailyDate},#{item.useNum},#{item.types})
</foreach>
</insert>

2.mybatis ExecutorType.BATCH

Mybatis内置的ExecutorType有3种 :SimpleExecutor、ReuseExecutor、BatchExecutor

默认的是SimpleExecutor查询一次关闭一次每次查询都会重新开启statement,

ReuseExecutor用的不多,他不会关闭statement,以sql语句作为key相关的statement作为value,可以重复利用以前的创建好的statement,前提是sql必须一致,

也就是mybatis做boundsql解析之前的原生sql,不包括组装的参数,sql相同组装参数相同则代表解析boundsql一致一个session情况下是会直接走一级缓存直接调出结果。

然而ReuseExecutor使用的也就是很多数据连接池库中常见的 PSCache 概念 。

BatchExecutor是正真的批量执行器,而batch模式重复使用已经预处理的语句,并且批量执行所有更新语句,显然batch性能将更优;

但batch模式也有自己的问题,比如在Insert操作时,在事务没有提交之前,是没有办法获取到自增的id,这在某型情形下是不符合业务要求的。

但是批量模式下可以手动提交和回滚也是会有不同好处。

//获取sqlsession
//从spring注入原有的sqlSessionTemplate
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
// 新获取一个模式为BATCH,自动提交为false的session
// 如果自动提交设置为true,将无法控制提交的条数,改为最后统一提交,可能导致内存溢出
SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
//通过新的session获取mapper
fooMapper=session.getMapper(FooMapper .class);
int size = 10000;
try {
for (int i = 0; i < size; i++) {
Foo foo = new Foo();
foo.setName(String.valueOf(System.currentTimeMillis()));
fooMapper.insert(foo);
if (i % 1000 == 0 || i == size - 1) {
//手动每1000个一提交,提交后无法回滚
session.commit();
//清理缓存,防止溢出
session.clearCache();
}
}
}catch(
Exception e) {
//没有提交的数据可以回滚
session.rollback();
}finally {
session.close();
}

第二数据冲突,第三数据重跑更新操作

这两个一起讲,因为一般情况下,数据重跑也会存在数据冲突,一般就主键以及唯一索引冲突。

在批量更插入一般这样的情况下,对于冲突的数据一般来说是要做更新操作的(前提是有做过自己的validation)。

但是又不可以方便对数据进行先查询再决定进行插入操作还是更新操作,这样批量操作时执行效率太低,。

mybatis批量中支持ON DUPLICATE KEY UPDATE用法。

也就是允许insert语句插入的行与表与现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新;

如果插入的行数据与现有表中记录的唯一索引或者主键不重复,则执行新纪录插入操作。

<insert id="batchInsert">
insert into day_time(daily_year,daily_month,daily_week,daily_date,use_num,types)
values
<foreach collection="list" item="item" separator=",">
(#{item.dailyYear},#{item.dailyMonth},#{item.dailyWeek},#{item.dailyDate},#{item.useNum},#{item.types})
</foreach>
<!-- 有则更新 -->
ON DUPLICATE KEY UPDATE
use_num = values(use_num)
</insert>

Mybatis中批量插入和一些问题的解决的更多相关文章

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

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

  2. 161102、MyBatis中批量插入

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

  3. MyBatis中批量插入数据对插入记录数的限制

    <基于Mybatis框架的批量数据插入的性能问题的探讨>(作者:魏静敏 刘欢杰 来源:<计算机光盘软件与应用> 2013 年第 19 期)中提到批量插入的记录数不能超过1000 ...

  4. mybatis中批量插入以及更新

    1:批量插入 批量插入就是在预编译的时候,将代码进行拼接,然后在数据库执行 <insert id="batchInsert" parameterType="java ...

  5. 【mybatis】mybatis中批量插入 批量更新 batch 进行insert 和 update,或者切割LIst进行批量操作

    ================================================================== 分别展示 mybatis 批量新增  和 批量更新   的操作: ...

  6. mybatis中批量插入数据

    <insert id="insertIntoDevAct" parameterType="java.util.List"><foreach c ...

  7. MyBatis向数据库中批量插入数据

    Foreach标签 foreach: collection:指定要遍历的集合; 表示传入过来的参数的数据类型.该参数为必选.要做 foreach 的对象,作为入参时,List 对象默认用 list 代 ...

  8. Mybatis+mysql批量插入性能分析测试

    前言 今天在网上看到一篇文章(后文中的文章指的就是它) https://www.jianshu.com/p/cce617be9f9e 发现了一种有关于mybatis批量插入的新方法,而且看了文章发现我 ...

  9. mybatis之批量插入

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

  10. mysql基础---->mybatis的批量插入(一)

    这里面记录一下使用mybatis处理mysql的批量插入的问题,测试有可能不准.只愿世间风景千般万般熙攘过后,字里行间,人我两忘,相对无言. mybatis的批量插入 我们的测试主体类是springb ...

随机推荐

  1. java pta第三次阶段性总结

    一.前言 这是这学期最后一次总结,这三次的pta大作业也是最后一次,这几次大作业主要写了电信计费系统的主要功能,第一次大作业是座机计费功能,第二次大作业是手机计费功能,第三次大作业是短信计费的功能.这 ...

  2. gitt如何将本地分支同远程分支进行关联

    将本地分支同远程分支进行关联,1.本地已经创建了分支test(test,是master以外自己创建的分支),而远程没有2种方法在远程创建分支test,并与本地分支进行关联: 方法1: git push ...

  3. vue el-tree 单选实现

    <el-tree :props="props" ref="treeList" :load="loadNode" check-stric ...

  4. 学习JavaScript 第二周

    分支结构中的switch switch(值&条件表达式){ case 值: 操作: break; case 值: 操作: break; ... default: 默认操作 } switch根据 ...

  5. 纯css实现卡券式半圆及阴影(整理)

    <!-- html部分 --> <div class="a"> <!-- a这个大卡片里边分上下两个卡片,对应上边灰色和下边白色部分 --> & ...

  6. applicationContext使用注解代替

    创建一个类SpringConfig @Configuration//证明这个类是spring的配置文件类 @ComponentScan("com.itheima")//扫描的哪些包 ...

  7. js 遍历对象属性

    function* objectEntries(obj) { let propKeys = Reflect.ownKeys(obj); for (let propKey of propKeys) { ...

  8. 决策树(DecisionTree)(附源码)

    决策树(DecisionTree)   决策树所属类别:监督学习,分类 优点:直观易懂,算法简单 缺点:容易过拟合,对连续型数据不太容易实现 实现方案:ID3,CART,C4.5 详细的资料见连接:别 ...

  9. Ubuntu VMWare安装纪要

    一.VMware虚拟机下载与安装 版本:VMware Workstation 16 Pro 二.Ubuntu下载与安装 版本:ubuntu-20.04.2.0-desktop-amd64.iso 三. ...

  10. Eclipse's Import error and remove

    1.导入项目之前,请确认工作空间编码已设置为utf-8:window->Preferences->General->Wrokspace->Text file encoding- ...