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

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

第一是执行效率: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. C++调用Python_____用Python C API

    项目需要用C++来处理用python处理的数据集,所以就需要在C++中调用python. 先介绍第一种方法,python文档中给出了python c api,可以实现C++与python的互动. 先新 ...

  2. python-官网下载安装教程

    1.官网地址:https://www.python.org/ 2.点击Downloads,选择Windows版本 3.找到对应版本,这里以3.9.12为例,选择结尾为executable instal ...

  3. suse 关闭 图形界面

    图形界面 /etc/systemd/system/default.target -> /usr/lib/systemd/system/graphical.target ln -s /usr/li ...

  4. springboot项目 报错No mapping for GET /css/bootstrap.css,前端无法展示样式

    说来也奇怪,前几天刚写完的项目 写的好好的 现在打开他就加载不了前端的静态资源了 报错No mapping for GET /css/bootstrap.css 解决方法: 新建一个配置类 ,将静态资 ...

  5. 杨辉三角形实现过程详解-C语言基础

    这一篇要探讨的是"杨辉三角形的实现以及如何人工走循环".涉及的知识点和内容很少,主要是想说明如何看懂循环,如何跟着循环走.属于C语言基础篇. 学习编程的人,在学习的初期,几乎都会接 ...

  6. (三).JavaScript的分支结构和循环结构

    1. 分支结构 1.1 分支语句之单分支 ①.语法: if(值,如果不是布尔值会强制转换成布尔值) { 代码块; } ②.案例: // 案例:如果a变量的值加键盘上输入的数大于100,就打印我爱你二狗 ...

  7. 艾思软件app开发公司帮您分析:开发一个APP多少钱?

    首先你要知道你所要开发的APP, 是不是已经成熟的相同的产品, 如果有的话那还是建议直接购买, 这种已经能满足你需求的成品APP价格会很便宜, 总成本一般也就1到2万的级别. 如果没有那就需要定制开发 ...

  8. 1012.Django中间件以及上下文处理器

    一.中间件 中间件的引入: Django中间件(Middleware)是一个轻量级.底层的"插入"系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出. d ...

  9. Sqoop连接数据库MySQL报错

    1.问题描述 (1)问题示例: [Hadoop@master TestDir]$ sqoop list-databases --connect jdbc:mysql://master:3306/ -- ...

  10. yield总结

    1.使用yield  i def my_generator(n): for i in range(n): temp = yield i print(f'我是{temp}') g = my_genera ...