当前位置: 首页 > article >正文

使用FastExcel时的单个和批量插入的问题

在我们用excel表进行插入导出的时候,通常使用easyexcel或者FastExcel,而fastexcel是easy的升级版本,今天我们就对使用FastExcel时往数据库插入数据的业务场景做出一个详细的剖析

场景1

现在我们数据库有一张组织表,组织表的字段如下

package com.example.tabledemo.pojo.entity;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.tabledemo.pojo.BaseEntity;
import lombok.Data;/*** @Author: wyz* @Date: 2025-03-25-10:18* @Description:*/
@TableName("organization")
@Data
public class OrganizationEntity extends BaseEntity {/*** 组织代码* <p>* 组织的唯一代码,用于标识不同的组织,不能为空。* </p>*/@TableField("org_code")private String orgCode;/*** 学院/组织名称* <p>* 组织的名称,用于描述组织的具体名称,不能为空。* </p>*/@TableField("org_name")private String orgName;/*** 组织类型* <p>* 组织的类型,用于描述组织的分类或性质,可以为空。* </p>*/@TableField("org_type")private String orgType;
}

现在我们业务要求是,组织code和组织name在插入的过程中是唯一性,也就是说这两个字段的数据是唯一的,那我们对这种情况有两种处理方式

方式1

我们应该最先想到的是在业务层进行重复值的判断,具体的流程如下

 然后我们按照此流程进行插入,但是这样会出现一个典型的多线程问题,就是我再查询结束之后,进行插入的时候,有另外一个线程也插入了,这时候我又插入成功,不是出现了问题,那么解决这个问题的方法也很简单,对资源上锁就行了

方式2

我们为org_name 和org_code分别在数据库中设置一个唯一性约束

create table organization
(id          bigint auto_increment comment '序号,主键,自增'primary key,org_code    varchar(50)                        not null comment '组织代码',org_name    varchar(100)                       not null comment '学院/组织名称',org_type    varchar(50)                        null comment '类型',status      int      default 0                 null comment '状态,默认为0(可用)',create_time datetime default CURRENT_TIMESTAMP null comment '创建时间,插入时自动填充',update_time datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间,插入和更新时自动填充',is_deleted  int      default 0                 null comment '逻辑删除标志,0表示未删除,1表示已删除',constraint org_codeunique (org_code),constraint org_nameunique (org_name)
)comment '组织信息表';

这样的话,在我们后台我们只需要关注插入的问题就行了,甚至修改的时候都不需要关心数据重复性的问题,因为在mysql底层,他会为每一个设置唯一性约束的字段创建一个索引,索引是b+树结构的,每次插入的时候会查询是否有这个索引,没有就插入,有就会报错

对应的java代码如下,我们不需要加事务是因为 这是对单表进行的纯插入删除操作,无需回滚,插入不成功我们数据库有唯一性约束数据库会自动禁止插入,而且在 mybatisplus的saveOrupdate方法中也有事务管理

   @Override
//    @Transactional(rollbackFor = Exception.class)无需事务public Result add(OrganizationRequest.addOrganization addOrganization) {OrganizationEntity organizationEntity = new OrganizationEntity();BeanUtil.copyProperties(addOrganization,organizationEntity);try {boolean b = saveOrUpdate(organizationEntity);return  Result.success(b);}catch (Exception e){if (e.getCause() instanceof SQLException) {SQLException sqlException = (SQLException) e.getCause();if (sqlException.getErrorCode() == 1062) { // MySQL 唯一性约束错误码return  Result.fail("组织名称或代码已存在,请勿重复插入!");}}return  Result.fail("数据库操作失败:" + e.getMessage());}}

问题1

当我们组织表信息量大了以后,我们每一次数据的插入都会使得mysql底层的索引的b+树结构改变,这种IO带来的开销无疑是越来越大的,所以,根据这个延申出来的解决方案也有几种

对mysql进行分库分表,然后让name和code做一次hash,根据不同的hash找到不同的表,然后进行数据的插入等这样能减少重建索引带来的IO开销。但是无论是哪种方法,都有一定的优缺点,看我们如何选择了吧

场景二

现在做的是一个excel表,我们填充完数据之后,需要批量导入,这时候org_name 和org_code也是需要唯一的,同样的也有两种方式,就是我们上文所说的,只是问题从 单个插入变成了批量插入。

而批量插入在数据库中的事务也同样延申出来的许多的问题

问题1

我在使用数据库 原始的sql进行批量插入的时候,假如有3条数据ABC,B数据和C数据一样,这时候如果我加了唯一性约束,会不会导致A插入成功,B,C两条数据没有插入成功下面我们来测试一下

我们现在拿到的是最新的数据

我们插入一下看看

我们再次查询一下数据库看一下

数据并没有变化,说明了在我们用values的时候,如果加了唯一性约束,这些批量插入的后面是同一个事务的,只要有一个失败,就会回滚所有的数据。

那我们再看同一个事务下,三条数据分批次插入的情况

显而易见,分批次插入的话,只有出现异常的数据不会被插入。

那么我们再来分析,假如说 现在 我们批量插入上面三条数据,那么第一条成功了,那么第二条还没有插入的时候,这时候这个字段的唯一索引变化是怎么样的,这时候唯一索引会带来额外的额外的io开销吗?

我们看下面一张图

我是按照红字的顺序进行事务的数据插入操作的,当我进行到4的时候,我5没有提交事务,这时候4会一直阻塞,原因是 REPEATABLE READ 隔离级别下,事务会持有插入的行的排他锁(X Lock),直到事务提交或回滚。  

我们再回来看索引的问题,当我们事务没有提交的时候,也就是步骤进行到3的时候,其实mysql已经为我们插入的这条数据加了唯一性索引了,假如这时候出现了异常,导致了事务回滚,那么索引就会重新取消,这也时带来io开销

其实解决情况已经很明了了,如果不想让数据库有多的索引的io开销,那么我们就要在代码层面控制,先查询所有数据,然后比对唯一性,要么就是 数据库层面控制,

如果是在数据库层面控制,要注意 插入的时候不要用for循环单条插入,而是saveBacth批量插入,如果非用for循环单挑插入,记得使用spring的事务注解,就跟我们前面说的一样,如果是设计多条数据的改变,而且需要回滚所有,这时候记得加事务

    @Override
//    @Transactional(rollbackFor = Exception.class)public void doAfterAllAnalysed(AnalysisContext context) {log.info("所有数据解析完成!");// 字段唯一性约束 可以 用mysql 自己的 也可用 代码逻辑判断List<OrganizationEntity> organizationEntities = BeanUtil.copyToList(list, OrganizationEntity.class);
//                    boolean b = organizationService.saveBatch(organizationEntities);
//            log.info("保存成功");try {boolean b = organizationService.saveBatch(organizationEntities);log.info("保存成功");}catch (Exception e){if (e.getCause() instanceof SQLException) {SQLException sqlException = (SQLException) e.getCause();if (sqlException.getErrorCode() == 1062) { // MySQL 唯一性约束错误码throw  new RuntimeException("组织名称或代码已存在,请勿重复插入!");}}throw  new RuntimeException("数据库操作失败:" + e.getMessage());}}

而在我的代码中为什么我把事务注解注释掉了,因为再mybatisplus中,他的saveBatch方法默认加了事务

相关文章:

使用FastExcel时的单个和批量插入的问题

在我们用excel表进行插入导出的时候&#xff0c;通常使用easyexcel或者FastExcel&#xff0c;而fastexcel是easy的升级版本&#xff0c;今天我们就对使用FastExcel时往数据库插入数据的业务场景做出一个详细的剖析 场景1 现在我们数据库有一张组织表&#xff0c;组织表的字段…...

交换技术综合实验

一、实验拓扑 二、实验要求 内网IP地址使用172.16.0.0/16分配。 SW1和SW2之间互为备份。 VRRP/STP/VLAN/Eth-trunk均使用。 所有PC通过DHCP获取IP地址。 ISP只能配置IP地址。 所有电脑可以正常访问ISP路由器。 三、实验步骤 基于172.16.0.0/16进行划分 172.16.2.0/24&…...

软件工程之软件开发模型(瀑布、迭代、敏捷、DevOps)

1. 瀑布模型&#xff08;Waterfall Model&#xff09; 定义与流程 瀑布模型是线性顺序的开发流程&#xff0c;包含需求分析、设计、编码、测试、维护等阶段&#xff0c;每个阶段完成后才能进入下一阶段&#xff0c;类似“瀑布流水”逐级推进。 核心特点 严格阶段划分&#…...

Display Serializer、Camera Deserializer(Camera Des)和SerDes‌ 加解串应用

‌1. 概述&#xff1a;三者的核心定位‌ ‌(1) SerDes&#xff08;Serializer/Deserializer&#xff09;‌ ‌定义‌&#xff1a;通用高速数据传输技术&#xff0c;实现‌并行↔串行‌双向转换。‌角色‌&#xff1a;数据链路的“翻译官”&#xff0c;解决并行传输的带宽与距…...

Redis 常用数据结构及其对应的业务场景(总结)

1. String&#xff08;字符串&#xff09; 特点&#xff1a;最简单的键值对结构&#xff0c;可存储文本、数字或二进制数据&#xff08;最大 512MB&#xff09;。 适用场景&#xff1a; 缓存&#xff1a;存储用户信息、页面片段、商品详情等&#xff08;如 SET user:1 "{…...

记录Jmeter 利用BeanShell 脚本解析JSON字符串

下载org.json包(文档说明) #下载地址 https://www.json.org/ # github 地址 https://github.com/stleary/JSON-java # api 文档说明 https://resources.arcgis.com/en/help/arcobjects-java/api/arcobjects/com/esri/arcgis/server/json/JSONObject.htmlBeanShell脚本 import…...

深入解析音频:格式、同步及封装容器

物理音频和数字音频 物理音频 定义&#xff1a;物理音频就是声音在自然界中的物理表现形式&#xff0c;本质上是一种机械波&#xff0c;通过空气或其他介质传播。例如&#xff0c;当我们说话、乐器演奏或物体碰撞时&#xff0c;都会产生振动&#xff0c;这些振动会引起周围介…...

RPCGC阅读

24年的MM 创新 现有点云压缩工作主要集中在保真度优化上。 而在实际应用中&#xff0c;压缩的目的是促进机器分析。例如&#xff0c;在自动驾驶中&#xff0c;有损压缩会显着丢失户外场景的详细信息。在三维重建中&#xff0c;压缩过程也会导致场景数据中语义信息(Contour)的…...

医疗CMS高效管理:简化更新维护流程

内容概要 医疗行业内容管理系统&#xff08;CMS&#xff09;的核心价值在于应对医疗信息管理的多维复杂性。面对诊疗指南的动态更新、科研数据的快速迭代以及多机构协作需求&#xff0c;传统管理模式往往面临效率瓶颈与合规风险。现代化医疗CMS通过构建结构化权限管理矩阵&…...

《Spring Cloud Eureka 高可用集群实战:从零构建高可靠性的微服务注册中心》

从零构建高可用 Eureka 集群 | Spring Cloud 微服务架构深度实践指南 本文核心内容基于《Spring Cloud 微服务架构开发》第1版整理&#xff0c;结合生产级实践经验优化 实验环境&#xff1a;IntelliJ IDEA 2024 | JDK 1.8| Spring Boot 2.1.7.RELEASE | Spring Cloud Greenwich…...

PyQt6实例_批量下载pdf工具_主线程启用线程池

目录 前置&#xff1a; 代码&#xff1a; 视频&#xff1a; 前置&#xff1a; 1 本系列将以 “PyQt6实例_批量下载pdf工具”开头&#xff0c;放在 【PyQt6实例】 专栏 2 本系列涉及到的PyQt6知识点&#xff1a; 线程池&#xff1a;QThreadPool,QRunnable&#xff1b; 信号与…...

DSP+AI综合应用案例1——三种波形识别(预告)

采用1kHz采样率&#xff0c;识别方波、正弦波、三角波三种波形&#xff0c;算法采用傅里叶变换与神经网络&#xff0c;识别结果如下&#xff1a; 可以达到1ms内实现检测&#xff0c;逐渐完善到CanMV K230 或MCU中&#xff0c;待续...

去噪算法大比拼

目录 效果图: 实现代码: 密集抖动 pip install pykalman 效果图: 实现代码: import numpy as np import cv2 import matplotlib.pyplot as plt from scipy.ndimage import gaussian_filter1d from scipy.signal import butter, filtfilt, savgol_filter from pykalma…...

浅拷贝或深拷贝js数组或对象的方法

在js中&#xff0c;直接通过赋值操作拷贝数组&#xff0c;会导致新旧数组互相影响。 这是因为数组、对象等数据属于引用类型&#xff08;Reference Type&#xff09;数据。对引用类型数据进行赋值操作时&#xff0c;实际上拷贝的是其内存地址的引用&#xff08;即指向堆内存中对…...

CKS认证 | Day3 K8s容器运行环境安全加固

一、最小特权原则&#xff08;POLP&#xff09; 1&#xff09;最小特权原则 (Principle of least privilege&#xff0c;POLP) &#xff1a; 是一种信息安全概念&#xff0c;即为用户提供执行其工作职责所需的最 小权限等级或许可。 最小特权原则被广泛认为是网络安全的最佳实…...

28_跨域

目录 promise promise的基本语法 async await try catch promise 静态方法 跨域 跨域的解决方案 1-cors ​编辑 2-jsonp方案 3-代理服务器 promise promise 是一个es6新增的语法 承诺的意思 作用:是专门用来解决回调地狱!!!! promise的基本语法 // 基本语法:// Pr…...

Stable Diffusion太慢?国内Midjourney平替方案—商用合规部署

一、AI绘画商用核心痛点&#xff08;为什么需要替代Stable Diffusion/Midjourney&#xff1f;&#xff09; 1. 速度慢&#xff0c;高并发支持差 Stable Diffusion&#xff1a;单卡GPU生成1张图需3-10秒&#xff0c;并发超过10任务易崩溃Midjourney&#xff1a;排队制&#xf…...

综述速读|086.04.24.Retrieval-Augmented Generation for AI-Generated Content A Survey

论文题目&#xff1a;Retrieval-Augmented Generation for AI-Generated Content: A Survey 论文地址&#xff1a;https://arxiv.org/abs/2402.19473 bib引用&#xff1a; misc{zhao2024retrievalaugmentedgenerationaigeneratedcontent,title{Retrieval-Augmented Generation…...

Spring @EnableAutoConfiguration 注解执行过程详解

Spring EnableAutoConfiguration 注解执行过程详解 核心流程 触发自动配置&#xff1a;通过 EnableAutoConfiguration 注解开启自动配置。加载配置类&#xff1a;根据 META-INF/spring.factories 文件加载默认的自动配置类。条件判断&#xff1a;每个自动配置类通过 Condition…...

JavaScript中的Math对象和随机数

目录 一、常用数学方法 1. 数值处理 2. 极值与运算 3. 三角函数&#xff08;参数为弧度&#xff09; 4. 对数与指数 5. 常量 二、随机数生成 Math.random() 1. 基础范围控制 2. 整数随机数 三、实际应用场景 1. 随机颜色生成 2. 数组随机排序 3. 概率控制 四、注…...

lxd-dashboard 图形管理LXD/LXC

前言 LXD-WEBGUI是一个完全用AngularJS编写的Web应用程序,无需应用服务器、数据库或其他后端服务支持。只需要简单地托管静态HTML和JavaScript文件,就能立即投入使用。这个项目目前处于测试阶段,提供了直观的用户界面,帮助用户便捷地管理和控制LXD实例。 安装lxd-dashboa…...

python纯终端实现图片查看器(全彩)(windows)

很多人作为命令行爱好者&#xff0c;无法在终端内直接查看图片是无法忍受的&#xff0c; 那就写一个&#xff01; 先直接上代码 import os import sys from PIL import Image import numpy as np import colorama import msvcrt # Windows专用# 初始化colorama colorama.ini…...

【动态规划篇】- 路径问题

62. 不同路径 题目链接&#xff1a; 62. 不同路径 题目解析&#xff1a; 状态表示 dp[i][j]表示&#xff1a;以[i][j]为终点时&#xff0c;一共有多少种路径。 状态转移方程 以[i][j]最近的几步来分析问题&#xff0c;要么从[i-1][j]位置向下走一步到达[i][j],要么从[i][j-1…...

《新凯来:半导体设备制造领域的“国家队”》

《新凯来&#xff1a;半导体设备制造领域的“国家队”》 一、SEMICON China 爆火出圈&#xff1a;31 款设备背后的 “深圳力量” 1.1 展会现象级热度 在 2025 年 SEMICON China 展会现场&#xff0c;新凯来展台成了整届展会当之无愧的 “顶流”&#xff0c;被来自全球各地的专…...

AI大模型最新发布[update@202503]

OpenAI GPT-4o&#xff1a;多模态&#xff0c;“o”代表Omni&#xff0c;即全能的意思&#xff0c;凸显了其多功能的特性。 多模态交互&#xff0c;GPT-4o可以接受文本、音频和图像的任意组合作为输入&#xff0c;并生成文本、音频和图像的任意组合输出。实时推理能力&#x…...

深入浅出 Embedding

1. 什么是 Embedding? Embedding(嵌入)是一种将高维数据映射到低维连续空间的技术,用于表达数据的语义关系。简单来说,它是一种向量化表示,将文本、图像、用户行为等信息转换为数值向量,使得相似的数据在向量空间中距离更近。 2. 如何理解 Embedding? 2.1 浅显易懂的…...

java项目之基于ssm的乡镇自来水收费系统(源码+文档)

项目简介 乡镇自来水收费系统实现了以下功能&#xff1a; 乡镇自来水收费系统在Eclipse环境中&#xff0c;使用Java语言进行编码&#xff0c;使用Mysql创建数据表保存本系统产生的数据。系统可以提供信息显示和相应服务&#xff0c;其管理员管理水表&#xff0c;审核用户更换…...

Java实战:实现用户的登录注册功能

系列文章目录 Java文件 I/O流的操作实战和高级UI组件和事件监听的综合 文章目录 系列文章目录前言一、大致流程思路分析&#xff1a;二、定义用户类&#xff1a;三、服务层的实现&#xff1a; 1.保护用户数据功能的实现2.登录操作的实现 四、实现用户的注册界面&#xff1a; 大…...

Spring AI MCP 架构详解

Spring AI MCP 架构详解 1.什么是MCP? MCP 是一种开放协议&#xff0c;它对应用程序向大语言模型&#xff08;LLMs&#xff09;提供上下文信息的方式进行了标准化。可以把 MCP 想象成人工智能应用程序的 USB-C 接口。就像 USB-C 为将设备连接到各种外围设备和配件提供了一种…...

目标识别与双目测距(1)环境搭建:Ubuntu+yolov5+pcl库

环境情况 ubuntu 18.04 → 20.04&#xff08;最终&#xff09; 安装Ubuntu1804虚拟机系统 Anaconda&#xff1a;可参考我的另一篇文章 Python 3.6.13 → 3.8&#xff08;最终&#xff09;Anaconda3-2021.05 目标识别&#xff1a;YOLOv5相关 1、安装git sudo apt install gi…...