【mybatis的批量操作】


在日常开发中,如果要操作数据库的话,或多或少都会遇到批量数据的处理,我们公司使用的mybaits-plus作为持久层的框架,今天就简单介绍一下mybaits批量操作数据库的几种方式。

1.循环插入

其实这种方式并不是批量插入,只是在日常开发中,使用这种方式的还是比较多的。

 代码解读
@RunWith(SpringRunner.class)
@SpringBootTest
public class BatchTest {@Resourceprivate StudentMapper studentMapper;@Testpublic void test(){List<Student> students = generateStudentData(100);long start = System.currentTimeMillis();students.forEach(studentMapper::insert);System.out.println("循环插入: " + students.size() + " 条数据,共计耗时:" + (System.currentTimeMillis() - start) + " 毫秒");}public static List<Student> generateStudentData(int size){List<Student> list = new ArrayList<>(size);Random random = new Random();for (int i = 0; i < size; i++) {Student student = new Student();student.setName("zhangsan-" + i);student.setAge(random.nextInt(40));student.setPhone("15077828899");student.setBirthday(LocalDateTime.now());list.add(student);}return list;}
}

2.foreach方式插入

 代码解读@RunWith(SpringRunner.class)
@SpringBootTest
public class BatchTest {@Resourceprivate StudentMapper studentMapper;@Testpublic void test3(){List<Student> students = generateStudentData(100);long foreachStart = System.currentTimeMillis();studentMapper.insertBatch(students);System.out.println("foreach插入: " + students.size() + " 条数据,共计耗时:" + (System.currentTimeMillis() - foreachStart) + " 毫秒");}public static List<Student> generateStudentData(int size){List<Student> list = new ArrayList<>(size);Random random = new Random();for (int i = 0; i < size; i++) {Student student = new Student();student.setName("zhangsan-" + i);student.setAge(random.nextInt(40));student.setPhone("15077828899");student.setBirthday(LocalDateTime.now());list.add(student);}return list;}
}

StudentMapper 接口如下:

 代码解读public interface StudentMapper extends BaseMapper<Student> {/*** 批量插入*/int insertBatch(@Param("entities") List<Student> entities);/*** 批量更新或者插入*/int insertOrUpdateBatch(@Param("entities") List<Student> entities);}

StudentMapper.xml内容如下:

xml 代码解读<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.efreight.oss.transfer.dao.StudentMapper"><resultMap type="com.efreight.oss.transfer.entity.Student" id="StudentMap"><result property="id" column="id" jdbcType="INTEGER"/><result property="name" column="name" jdbcType="VARCHAR"/><result property="age" column="age" jdbcType="INTEGER"/><result property="birthday" column="birthday" jdbcType="TIMESTAMP"/><result property="phone" column="phone" jdbcType="VARCHAR"/></resultMap><!-- 批量插入 --><insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">insert into cargo.student(name, age, birthday, phone)values<foreach collection="entities" item="entity" separator=",">(#{entity.name}, #{entity.age}, #{entity.birthday}, #{entity.phone})</foreach></insert><!-- 批量插入或按主键更新 --><insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">insert into cargo.student(name, age, birthday, phone)values<foreach collection="entities" item="entity" separator=",">(#{entity.name}, #{entity.age}, #{entity.birthday}, #{entity.phone})</foreach>on duplicate key updatename = values(name) , age = values(age) , birthday = values(birthday) , phone = values(phone)</insert></mapper>

搭配 useGeneratedKeys="true"keyProperty="id" 属性(这个id是javaBean的属性),可以获取自增主键,有时候这个主键我们是非常需要的。

3.批处理方式插入

通过 ExecutorType.BATCH来构建一个可以完成批处理工作的执行器

 代码解读@RunWith(SpringRunner.class)
@SpringBootTest
public class BatchTest {@Resourceprivate StudentMapper studentMapper;@Resourceprivate SqlSessionTemplate sqlSessionTemplate;@Testpublic void test2(){List<Student> students = generateStudentData(100);long batchStart = System.currentTimeMillis();try(SqlSession sqlSession = this.sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false)) {StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);for (int i = 0; i < students.size(); i++) {  studentMapper.insert(students.get(i));  if (i % 1000 == 0 || i == students.size() - 1) {  sqlSession.flushStatements();  }  }  sqlSession.commit();}System.out.println("mybatis批处理插入: " + students.size() + " 条数据,共计耗时:" + (System.currentTimeMillis() - batchStart) + " 毫秒");}public static List<Student> generateStudentData(int size){List<Student> list = new ArrayList<>(size);Random random = new Random();for (int i = 0; i < size; i++) {Student student = new Student();student.setName("zhangsan-" + i);student.setAge(random.nextInt(40));student.setPhone("15077828899");student.setBirthday(LocalDateTime.now());list.add(student);}return list;}
}

注意:批处理方式是无法获取自增主键的。

顺便说一下,现在使用mybatis-plus的也非常多,他也提供了批量插入的功能,它内部使用的就是ExecutorType.BATCH 来构建的。

image.png

关于三者性能的比较大家可以跑下看看,循环插入的方式性能最差,能不用就尽量不用,在foreach批处理中,我测试发现foreach的性能最好(我用的MySQL是5.7),所以项目中我们批处理使用的都是foreach, 因为一般我们一般批量插入最多也就2000条左右的数据,但是大家可以根据自己机器的实际情况,去跑一下看看。

插入方式100条1000条10000条10万条
循环插入1599 毫秒14336 毫秒140793 毫秒*
foreach62 毫秒364 毫秒3249 毫秒23940 毫秒
批处理321 毫秒6868 毫秒72851 毫秒457005 毫秒

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/51186.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

功能实现——使用 OpenPDF 将 HTML 转换为 PDF,并将其上传到 FTP 服务器

目录 1.需求分析2.项目环境搭建3.将 HTML 转换为 PDF3.1.代码实现mail.htmlHtmlToPDFController.javaPDFConverterService.javaPDFConverterServiceImpl.java 3.2.测试3.3.注意事项 4.将生成的 PDF 上传到 FTP 服务器4.1.搭建 FTP 服务器4.2.配置文件4.3.代码实现FtpUtil.javaF…

谷粒商城实战笔记-75-商品服务-API-品牌管理-品牌分类关联与级联更新

文章目录 一&#xff0c;引入Mybatis Plus分页插件二&#xff0c;品牌列表的模糊查询三&#xff0c;增加品牌测试数据四&#xff0c;开发后台品牌关联分类接口1&#xff0c;接口product/categorybrandrelation/catelog/list2&#xff0c;接口product/categorybrandrelation/sav…

汽车长翅膀:GPU 是如何加速深度学习模型的训练和推理过程的?

编者按&#xff1a;深度学习的飞速发展离不开硬件技术的突破&#xff0c;而 GPU 的崛起无疑是其中最大的推力之一。但你是否曾好奇过&#xff0c;为何一行简单的“.to(‘cuda’)”代码就能让模型的训练速度突飞猛进&#xff1f;本文正是为解答这个疑问而作。 作者以独特的视角&…

数仓架构解析(第45天)

系列文章目录 经典数仓架构传统离线大数据架构 文章目录 系列文章目录烂橙子-终生成长群群主前言1. 经典数仓架构2. 传统离线大数据架构 烂橙子-终生成长群群主 前言 经典数仓架构 传统离线大数据架构 背景解析 1. 经典数仓架构 1991年&#xff0c;比尔恩门&#xff08;Bill…

牛客算法题解:数字统计、两个数组的交集、点击消除

目录 BC153 [NOIP2010]数字统计 ▐ 题解 NC313 两个数组的交集 ▐ 题解 AB5 点击消除 ▐ 题解 BC153 [NOIP2010]数字统计 题目描述&#xff1a; 题目链接&#xff1a; [NOIP2010]数字统计_牛客题霸_牛客网 (nowcoder.com) ▐ 题解 题目要求统计出某段数组中一共有多少个…

关于Buffer和Channel的注意事项和细节

1.举例 package org.example.demo;import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.util.RandomAccess;/*** MappedByteBuffer可…

动量参数(Momentum Parameter)

动量参数&#xff08;Momentum Parameter&#xff09;在机器学习中指的是一种用于加速梯度下降算法的技术&#xff0c;特别是深度学习中优化神经网络权重时。简单来说&#xff0c;动量参数是一种帮助优化过程加速并减少震荡的技术。 具体来说&#xff0c;动量参数具有以下特点…

网络编程——wireshark抓包、tcp粘包

目录 一、前言 1.1 什么是粘包 1.2 为什么UDP不会粘包 二、编写程序 文件树 客户端程序 服务器程序 tcp程序 头文件 makefile 三、 实验现象 四、改进实验 五、小作业 一、前言 最近在做网络芯片的驱动&#xff0c;验证功能的时候需要借助wireshark这个工具&…

猫头虎分享:Numpy知识点一文带你详细学习np.random.randn()

&#x1f42f; 猫头虎分享&#xff1a;Numpy知识点一文带你详细学习np.random.randn() 摘要 Numpy 是数据科学和机器学习领域中不可或缺的工具。在本篇文章中&#xff0c;我们将深入探讨 np.random.randn()&#xff0c;一个用于生成标准正态分布的强大函数。通过详细的代码示…

Android Studio 一键删除 Recent Projects信息的方法

Android Studio打开项目多了就一堆最近项目的记录&#xff0c;在IDE里面只能一个个手动删除。 File - Recent Projects 解决方案&#xff1a;修改配置文件 Note&#xff1a;方法不唯一。 Android Studio 存储了一个包含最近打开项目信息的配置文件。通过手动编辑或删除recentP…

科普文:kubernets原理

kubernetes 已经成为容器编排领域的王者&#xff0c;它是基于容器的集群编排引擎&#xff0c;具备扩展集群、滚动升级回滚、弹性伸缩、自动治愈、服务发现等多种特性能力。 本文将带着大家快速了解 kubernetes &#xff0c;了解我们谈论 kubernetes 都是在谈论什么。 一、背…

详细介绍BIO、NIO、IO多路复用(select、poll、epoll)

BIO、NIO、IO多路复用 BIO(Blocking IO)NIO(Non-blocking IO) 同步非阻塞IOIO多路复用selectpollepoll Redis的IO多路复用 BIO(Blocking IO) 最基础的IO模型&#xff0c;当进行IO操作时&#xff0c;线程会被阻塞&#xff0c;直到操作完成。 比如read和write&#xff0c;通常IO…

Python的输入规则

Python的输入特别有意思&#xff0c;它和C的输入不一样&#xff0c;它的输入的原型是类似于C的string类型&#xff0c;但是对于一些有意思的算法题来说&#xff0c;光是读入string型的内容并不容易解题&#xff0c;于是我们可以从两个方面来将输入给转化。 1. 先使用函数input…

SGLang 大模型推理框架 qwen2部署使用案例;openai接口调用、requests调用

参考: https://github.com/sgl-project/sglang 纯python写,号称比vllm、tensorRT还快 暂时支持模型 安装 可以pip、源码、docker安装,这里用的pip 注意flashinfer安装最新版,不然会可能出错误ImportError: cannot import name ‘top_k_top_p_sampling_from_probs’ fr…

EtherNet/IP转Profinet协议网关(经典配置案例)

怎么样才能把EtherNet/IP和Profinet网络连接起来呢?这几天有几个朋友问到了这个问题&#xff0c;作者在这里统一为大家详细说明一下。其实有一个设备可以很轻松地解决这个问题&#xff0c;名为JM-PN-EIP&#xff0c;下面是详细介绍。 一&#xff0c;设备主要功能 1、捷米特J…

nodepad++已打开的文件怎么按照字母/文字顺序排列?

nodepad已打开的文件怎么按照字母/文字顺序排列&#xff1f; 点击菜单栏 “窗口” -> “排序方式” &#xff08;可选择升序或降序&#xff09;

加密货币赋能跨境电商:PayPal供应链金融服务如何引领行业新趋势

跨境电商行业近年来呈现出爆发式增长&#xff0c;随着全球化贸易壁垒的降低和数字经济的快速发展&#xff0c;越来越多的商家和消费者跨越国界进行交易。根据eMarketer的数据&#xff0c;全球跨境电商交易额在2023年已超过4万亿美元&#xff0c;并预计在未来几年内仍将保持两位…

centos7 xtrabackup mysql(8)增量备份(1)

centos7 xtrabackup mysql&#xff08;8&#xff09;增量备份&#xff08;1&#xff09; 参考 xtrabackup-8.0的安装、备份以及恢复&#xff08;innoxtrabackup有待测试&#xff09; https://blog.csdn.net/DWJRIVER/article/details/117792271 https://blog.csdn.net/qq_28…

开发环境搭建——Tomcat安装配置

一、Tomcat安装 1、解压下载好的安装包&#xff0c;将解压后的文件放到任意一个盘中&#xff0c;注意&#xff0c;尽量不要有中文 2、运行Tomcat&#xff0c;测试Tomcat是否正常连接使用 双击bin目录下的startup.bat文件&#xff0c;启动Tomcat 出现下面的界面标识Tomcat启动…

顺序栈和链栈的操作实现

目录 一. 前言 二.顺序栈 三. 链栈 一. 前言 简而言之&#xff0c;顺序栈就是栈的顺序存储&#xff0c;链栈就是栈的链式存储。 二.顺序栈 下面我们来看下顺序栈的结构定义&#xff1a; typedef char SElemType; #define MAXSIZE 100 typedef struct{SElemType * base; //…