Mybatis中批量插入和一些问题的解决
批量插入有三个问题,第一是执行效率,第二数据冲突,第三数据重跑更新操作。
一般对于这样的问题有以下操作方法。
第一是执行效率: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中批量插入和一些问题的解决的更多相关文章
- mybatis中批量插入的两种方式(高效插入)
MyBatis简介 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用 ...
- 161102、MyBatis中批量插入
方法一: <insert id="insertbatch" parameterType="java.util.List"> <selectKe ...
- MyBatis中批量插入数据对插入记录数的限制
<基于Mybatis框架的批量数据插入的性能问题的探讨>(作者:魏静敏 刘欢杰 来源:<计算机光盘软件与应用> 2013 年第 19 期)中提到批量插入的记录数不能超过1000 ...
- mybatis中批量插入以及更新
1:批量插入 批量插入就是在预编译的时候,将代码进行拼接,然后在数据库执行 <insert id="batchInsert" parameterType="java ...
- 【mybatis】mybatis中批量插入 批量更新 batch 进行insert 和 update,或者切割LIst进行批量操作
================================================================== 分别展示 mybatis 批量新增 和 批量更新 的操作: ...
- mybatis中批量插入数据
<insert id="insertIntoDevAct" parameterType="java.util.List"><foreach c ...
- MyBatis向数据库中批量插入数据
Foreach标签 foreach: collection:指定要遍历的集合; 表示传入过来的参数的数据类型.该参数为必选.要做 foreach 的对象,作为入参时,List 对象默认用 list 代 ...
- Mybatis+mysql批量插入性能分析测试
前言 今天在网上看到一篇文章(后文中的文章指的就是它) https://www.jianshu.com/p/cce617be9f9e 发现了一种有关于mybatis批量插入的新方法,而且看了文章发现我 ...
- mybatis之批量插入
一.导入功能优化 普通for循环,对于导入大量数据时非常耗时.可以通过Mybatis的批量插入功能提高效率.每批次导入的数据不能太多,否则会报错.通过测试发现,每批次200条为宜. 测试结果: 开启事 ...
- mysql基础---->mybatis的批量插入(一)
这里面记录一下使用mybatis处理mysql的批量插入的问题,测试有可能不准.只愿世间风景千般万般熙攘过后,字里行间,人我两忘,相对无言. mybatis的批量插入 我们的测试主体类是springb ...
随机推荐
- 西瓜书 5.5 编写过程(标准BP与累计BP)
话不多说先用numpy表示出数据集 Y=['色泽','根蒂','敲声','纹理','脐部','触感','密度','含糖率','好瓜与否']D=np.array([[2,1,2,3,3,1,0.697, ...
- Ignore warnings
import warnings warnings.filterwarnings("ignore")
- Spring-IoC中Set和构造器注入
新建Maven工程 修改pom文件 1 <?xml version="1.0" encoding="UTF-8"?> 2 <project x ...
- json中有List集合时,转换List集合内元素的时间格式
1 public class User implements Serializable { 2 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" ...
- 微信小程序—标题栏
<template> <view :style="{paddingTop: statusBarHeight + 'px',background:bg}" clas ...
- Javaheima20
Java 学习内容 单元测试 反射 注解 动态代理 开发好的系统中存在很多的方法,如和对这些方法的正确性进行测试 如何在程序运行时取得到Class对象,然后取获得Class中的每个成分 注解是什么,具 ...
- JVM-创建一个对象的详细过程
Person person=new Person(): 1.现在栈中申请一个自己的栈空间 2.类加载检查 每当使用new操作符创建一个对象时,类加载器都会从常量池中寻找该对象的符号引用,如果找到,则根 ...
- dockerflie
FROM newbe36524/aspnet:5.0-buster-slim AS base ENV TZ=Asia/Shanghai WORKDIR /app EXPOSE 3400 3400 RU ...
- 不同页面的 body设置
由于SPA页面的特性,传统的设置 body 背景色的方法并不通用. 解决方案:利用组件内的路由实现 第一种方式 // 实例创建之前 beforeCreate(){ document.querySele ...
- IOS开发基础之核心动画 基础动画、关键帧、组动画案例
// // ViewController.m // 30-核心动画 // // #import "ViewController.h" @interface ViewControll ...