简单的mybatis batch插入批处理

简单的mybatis batch插入批处理

1.需求

公司的权限管理功能有一个岗位关联资源的分配操作,如果新增一个岗位,有时候需要将资源全部挂上去,原有的是for循环插入资源信息,发现有时候执行速度过慢,所以此处想修改为批处理模式进行处理,提高一下效率优化使用感受。此处简单记录一下批处理操作步骤,方便后续学习复习使用。

2. 具体实现步骤

主要就是引入mybatis-plus包,自己对应服务的数据库包,数据库驱动包,连接池包等基础环境包。引入包后编写mybatis-plus配置文件,数据库连接配置文件。将配置文件配置好后则编写数据库对应实体以及对应的删除新增mapper类,最后则是编写测试类即可。

我们本次测试以单条插入以及批量插入进行对比,插入没有对xml中使用<foreach>循环拼接sql形式进行对比,这种形式数据量少的情况下效率与批量插入效率相当,但是如果数据量过大数据库会有条数限制,oracle条数限制1000,而mysql则是需要修改数据库的配置文件 my.ini 中的 max_allowed_packet 参数,一般情况是不允许过长的,所以数据量过大我们不考虑这种拼接sql的处理方式。

2.1 具体引入坐标

我在测试demo项目中引入坐标如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.git</groupId><artifactId>docker-hello</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><properties><maven.deploy.skip>true</maven.deploy.skip><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><mybatis-plus.version>3.3.0</mybatis-plus.version><fastjson.version>1.2.83</fastjson.version><druid.version>1.2.4</druid.version><hutool.version>5.5.7</hutool.version><lombok.version>1.18.6</lombok.version><mapstruct.version>1.4.1.Final</mapstruct.version><swagger.version>3.0.0</swagger.version><elasticjob.version>3.0.0-RC1</elasticjob.version><druid.version>1.2.4</druid.version><poi-tl.version>1.9.1</poi-tl.version><poi.version>4.1.2</poi.version><easyexcel.version>2.2.8</easyexcel.version></properties><!-- springboot dependency --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.8.RELEASE</version><relativePath/></parent><dependencyManagement><dependencies><!-- hutool --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><!-- mapstruct --><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${mapstruct.version}</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!-- log4j2日志使用包 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.3.4</version></dependency><!-- 测试包 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><!-- 批处理测试使用包 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency></dependencies><build><plugins><!-- compiler --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><annotationProcessorPaths><path><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${mapstruct.version}</version></path><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></path></annotationProcessorPaths></configuration></plugin><!-- package --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2.2 yml配置文件

测试demo项目的yml配置文件内容如下:

server:port: 8088
spring:application:name: docker-hello  # 应用程序名称,用于 Spring Cloud 的服务发现和服务注册# 数据源配置datasource:type: com.alibaba.druid.pool.DruidDataSource  # 数据源类型,这里使用的是 Druid 数据源driver-class-name: com.mysql.cj.jdbc.Driver  # MySQL 驱动类名url: jdbc:mysql://192.168.138.129:3306/test?useUnicode=true&characterEncoding=utf-8  # 数据库连接 URLusername: root  # 数据库用户名password: 101022  # 数据库密码redis:database: 0  # Redis 数据库索引,默认为 0host: 192.168.138.129  # Redis 服务器的 IP 地址port: 6379  # Redis 服务器的端口号timeout: 20000  # Redis 连接超时时间,单位为毫秒# springboot2.x以上如此配置,由于2.x的客户端是lettucelettuce:pool:max-active: 8  # 最大活动连接数,默认为 8min-idle: 0  # 最小空闲连接数,默认为 0max-idle: 8  # 最大空闲连接数,默认为 8max-wait: 10000ms  # 获取连接的最大等待时间,默认为 10000 毫秒# mybatis plus配置
mybatis-plus:# 扫描 mapper.xml 文件位置mapper-locations: classpath*:/mappers/*Mapper.xml# 别名类文件夹位置type-aliases-package: cn.git.entity# 基本配置configuration:# 驼峰模式map-underscore-to-camel-case: true# 二级缓存cache-enabled: false

2.3 实体以及mapper

对应实体类内容如下:

package cn.git.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.math.BigDecimal;/*** @description: 产品表* @program: bank-credit-sy* @author: lixuchun* @create: 2024-09-24*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("product")
public class Product {@TableId(value = "id", type = IdType.ASSIGN_ID)private String id;@TableField("name")private String name;@TableField("rate")private BigDecimal rate;@TableField("amount")private BigDecimal amount;@TableField("raised")private BigDecimal raised;@TableField("cycle")private Integer cycle;@TableField("end_Time")private String endTime;}

对应的mapper内容如下:

package cn.git.mapper;import cn.git.entity.Product;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** @description: 产品mapper* @program: bank-credit-sy* @author: lixuchun* @create: 2024-09-24*/
public interface ProductMapper extends BaseMapper<Product> {
}

数据库建测试产品表使用建表语句如下:

CREATE DATABASE IF NOT EXISTS `test`;
USE `test`;
DROP TABLE IF EXISTS `product`;
CREATE TABLE `product` (`id` varchar(32) NOT NULL,`name` varchar(20) DEFAULT NULL,`rate` double DEFAULT NULL,`amount` double DEFAULT NULL,`raised` double DEFAULT NULL,`cycle` int(11) DEFAULT NULL,`end_Time` char(10) DEFAULT '0',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

2.4 编写测试类

我们主要测试批处理执行过程,观察执行过程与普通任务foreach执行的时间差别,所以此处直接在controller中调用测试,具体的controller内容如下:

package cn.git.controller;import cn.git.entity.Product;
import cn.git.mapper.ProductMapper;
import cn.hutool.core.util.IdUtil;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.math.BigDecimal;/*** @description: mybatis批量处理controller* @program: bank-credit-sy* @author: lixuchun* @create: 2024-09-24*/
@RestController
@RequestMapping("/batch")
public class BatchController {@Autowiredprivate SqlSessionFactory sqlSessionFactory;@Autowiredprivate ProductMapper productMapper;/*** 批量插入* * @return*/@GetMapping("/add/product")public String addProduct(){// 插入100000long start = System.currentTimeMillis();// 获取SqlSession,并开启批量执行模式SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);try {ProductMapper productMapper = session.getMapper(ProductMapper.class);for (int i = 0; i < 500000; i++) {Product product = new Product();product.setId(IdUtil.simpleUUID());product.setName("product" + i);product.setRate(new BigDecimal(i));product.setAmount(new BigDecimal(i));product.setRaised(new BigDecimal(i));product.setCycle(i);product.setEndTime("2024-09-24");productMapper.insert(product);// 测试异常回滚,可去除if (i == 99) {throw new RuntimeException("报错啦");}}System.out.println("开始批量提交commit");session.commit();} catch (Exception e) {// 事务回滚session.rollback();e.printStackTrace();return "插入失败";} finally {// 清除缓存, 关闭sessionsession.clearCache();session.close();}long end = System.currentTimeMillis();// 打印用时多少秒System.out.println("用时:" + (end - start) / 1000 + "秒");return "批量插入完成";}/*** 单条插入* * @return*/@GetMapping("/add/product2")public String addProduct2(){// 插入100000long start = System.currentTimeMillis();for (int i = 0; i < 500000; i++) {Product product = new Product();product.setId(IdUtil.simpleUUID());product.setName("product" + i);product.setRate(new BigDecimal(i));product.setAmount(new BigDecimal(i));product.setRaised(new BigDecimal(i));product.setCycle(i);product.setEndTime("2024-09-24");productMapper.insert(product);}long end = System.currentTimeMillis();// 打印用时多少秒System.out.println("用时:" + (end - start) / 1000 + "秒");return "单条插入完成";}}

3.测试

我们调用未执行批处理的接口 http://localhost:8088/batch/add/product2,使用foreach循环插入数据,我们观察调用时间为 108秒
在这里插入图片描述
我们调用使用批量插入的接口 http://localhost:8088/batch/add/product,我们观察调用的时间为 56秒
在这里插入图片描述
如果插入的数据表结构更复杂,表数据量更大的话,批量处理形式与普通单条插入区别将更大,推荐使用批量处理模式。

项目源码地址

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

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

相关文章

Spring Cloud Gateway 之动态uri 自定义过滤器

背景&#xff1a;第三方公司 请求本公司入参和出参一样的同一个接口&#xff0c;根据业务类型不一样需要不同业务微服务处理 &#xff0c;和第三方公司协商在请求头中加入业务类型方便我公司在网关成分发请求。 1&#xff1a;在spring cloud gateway yml 中加入路由 重点是 -…

数据结构之搜索二叉树

目录 一、什么是搜索二叉树 基本概念 特点 注意事项 二、搜索二叉树的C实现 2.0 构造与析构 2.1 插入 2.2 查找 2.3 删除 2.3.1 无牵无挂型 2.3.2 独生子女型 2.3.3 儿女双全型 三、搜索二叉树的应用 3.1 key搜索 3.2 key/value搜索 一、什么是搜索二叉树 搜索二…

数值计算 --- 平方根倒数快速算法(中)

平方根倒数快速算法(中) --- 向Greg Walsh致敬&#xff01; 在前面的介绍中&#xff0c;我们已经知道了这段代码的作者Greg Walsh在函数的最后使用了NR-iteration&#xff0c;且只用了一次NR-iteration就能达到比较理想的精度。这样一来&#xff0c;选择正确的初值就显得尤为重…

云原生|浅谈云原生中的对象存储之MinIO 的使用

一、什么是对象储存 对象存储&#xff08;Object Storage&#xff09;以对象的形式存储和管理数据&#xff0c;这些对象可以是任何类型的数据&#xff0c;例如 PDF&#xff0c;视频&#xff0c;音频&#xff0c;文本或其他文件类型。对象存储使用分布式存储架构&#xff0c;数据…

C语言贪吃蛇小游戏演示和说明

C语言贪吃蛇小游戏演示和说明 设计贪吃蛇游戏的主要目的是让大家夯实C语言基础&#xff0c;训练编程思维&#xff0c;培养解决问题的思路&#xff0c;领略多姿多彩的C语言。 游戏开始后&#xff0c;会在中间位置出现一条只有三个节点的贪吃蛇&#xff0c;并随机出现一个食物&am…

数据结构练习题————(二叉树)——考前必备合集!

今天在牛客网和力扣上带来了数据结构中二叉树的进阶练习题 1.二叉搜索树与双向链表———二叉搜索树与双向链表_牛客题霸_牛客网 (nowcoder.com) 2.二叉树遍历————二叉树遍历_牛客题霸_牛客网 (nowcoder.com) 3.二叉树的层序遍历————102. 二叉树的层序遍历 - 力扣&am…

寿司检测系统源码分享

寿司检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

一文了解高速工业相机

超高速相机是工业相机的一种&#xff0c;一般高速相机指的是数字工业相机&#xff0c;其一般安装在机器流水线上代替人眼来做测量和判断&#xff0c;通过数字图像摄取目标转换成图像信号&#xff0c;传送给专用的图像处理系统。 超高速工业相机的采集速率> 50Gb/s&#xff…

window系统DockerDesktop 部署windows容器

目录 参考文献1、安装Docker Desktop1.1 下载安装包1.2 安装教程1.3 异常解决 2、安装windows容器2.1 先启动DockerDesktop 软件界面2.2 检查docker版本2.3 拉取windows镜像2.4 网盘下载windows镜像 参考文献 windows容器docker中文官网 Docker: windows下跑windows镜像 1、安…

软件测试标准流程(思维导图版)

一套标准的流程在实际工作落地并执行起来&#xff0c;针对管理可起到很好的作用。 针对效率可在工作中不断的执行&#xff0c;执行后不断的进行优化&#xff0c;再次执行&#xff0c;在不断的工作实践中慢慢完善最终适用于整个团队。 这就是标准流程的作用与实际的好处&#…

华为申请鸿蒙甄选、鸿蒙优选商标,加词的注意!

近日华为在35类广告销售上申请鸿蒙智选、鸿蒙优选、鸿蒙精品&#xff0c;鸿蒙甄选等商标&#xff0c;后面所加的词智选、优选、精品、甄选等基本上是属于通用词。 这样在35类拿到鸿蒙通用词商标&#xff0c;需要先拿到“鸿蒙“商标&#xff0c;经普推知产商标老杨检索发现&…

【Linux】yum、vim、gcc使用(超详细)

目录 yum 安装软件 卸载软件 查看安装包 安装一下好玩的命令 vim vim基本操作 模式切换 命令集 vim批量注释 vim配置 gcc 函数库 小知识点&#xff1a; Linux中常见的软件安装方式 --------- 下载&&安装 a、yum/apt b、rpm安装包安装 c、源码安装 y…

周家庄智慧旅游小程序

项目概述 周家庄智慧旅游小程序将通过数字化手段提升游客的旅游体验&#xff0c;依托周家庄的自然与文化资源&#xff0c;打造智慧旅游新模式。该小程序将结合虚拟现实&#xff08;VR&#xff09;、增强现实&#xff08;AR&#xff09;和人工智能等技术&#xff0c;提供丰富的…

vue嵌套路由刷新页面空白问题

问题描述 在vue项目开发中遇到这样一个问题&#xff0c;在history模式下通过页面点击路由跳转可以打开页面&#xff0c;但是在当前页面刷新就空白了&#xff0c;如下&#xff1a; 点击路由跳转页面是有的 刷新页面就空白 代码 {path: "/home",name: "home&qu…

SQL常用数据过滤 - EXISTS运算符

SQL查询中的EXISTS运算符用于检查查询子句是否存在满足特定条件的记录&#xff0c;如果有一条或者多条记录存在&#xff0c;则返回True&#xff0c;否则返回False。 语法结构 SELECT column_name(s)FROM table_nameWHERE EXISTS(SELECT column_name FROM table_name WHERE co…

React学习笔记(2.0)

React事件绑定 语法&#xff1a;在对应标签上书写on事件&#xff08;比如onClick,onChange&#xff09;&#xff0c;注意和原生的事件区分&#xff0c;React的事件首字母要大写。 const handleChange(e:any)>{console.log(e);console.log(change事件触发);// e不是原生事件…

Acwing 最小生成树

最小生成树 最小生成树:由n个节点&#xff0c;和n-1条边构成的无向图被称为G的一棵生成树&#xff0c;在G的所有生成树中&#xff0c;边的权值之和最小的生成树&#xff0c;被称为G的最小生成树。&#xff08;换句话说就是用最小的代价把n个点都连起来&#xff09; Prim 算法…

初识Jenkins持续集成系统

随着软件开发复杂度的不断提高&#xff0c;团队成员之间如何更好地协同工作以确保软件开发的质量&#xff0c;已经慢慢成为开发过程中不可回避的问题。Jenkins 自动化部署可以解决集成、测试、部署等重复性的工作&#xff0c;工具集成的效率明显高于人工操作;并且持续集成可以更…

Java线程池详解

目录 前言 线程池概述 线程池的实现 线程池的构造 拒绝策略 任务队列 线程池的工作原理 线程池的监控 Executors线程池工厂 自定义线程池 使用线程池的好处 应用场景 总结 本文详细探讨了线程池在并发编程领域的应用&#xff0c;介绍了ThreadPoolExecutor的核心组…

MySQL的登录、访问、退出

一、登录&#xff1a; 访问MySQL服务器对应的命令&#xff1a;mysql.exe ,位置&#xff1a;C:\Program Files\MySQL\MySQL Server 8.0\bin &#xff08;mysql.exe需要带参数执行&#xff0c;所以直接在图形界面下执行该命令会自动结束&#xff09; 执行mysql.exe命令的时候出…