【精品】通用Mapper 批量更新bug解决方案
问题描述
环境:mysql8.x+mybatis3.5.13+tk.mybatis4.2.3
在使用tk.mybatis做批量更新时,程序会报错,说是执行的SQL语法错误,经研究源代码发现tk.mybatis在实现批量更新时是通过多次执行update语句实现的。这本身就不符合MySQL批量更新的语法,可以通过自定义Mapper的方式解决。
有关MySQL批量更新SQL语句的语法请参考:MySQL专有的SQL语句
解决方案
批量更新
- 接口
@RegisterMapper
public interface BatchUpdateByIdMapper<T> {/*** 批量更新* @param list* @return*/@UpdateProvider(type = BatchUpdateByIdProvider.class, method = "dynamicSQL")int batchUpdate(List<T> list);
}
- provider
public class BatchUpdateByIdProvider extends MapperTemplate {public BatchUpdateByIdProvider(Class<?> mapperClass, MapperHelper mapperHelper) {super(mapperClass, mapperHelper);}public String batchUpdate(MappedStatement statement) {//1.获取实体类对应的Class对象Class<?> entityClass = super.getEntityClass(statement);//2.获取实体类在数据库中对应的表名String tableName = super.tableName(entityClass);//3.生成update子句String update = SqlHelper.updateTable(entityClass, tableName);//4.创建StringBuilder用于拼接SQL语句的各个组成部分StringBuilder sb = new StringBuilder(update);sb.append("<trim prefix=\"set\" suffixOverrides=\",\">");//5.获取所有字段信息Set<EntityColumn> columns = EntityHelper.getColumns(entityClass);//获取主键EntityColumn pkEntityColumn = null;for (EntityColumn entityColumn : columns) {boolean isPrimaryKey = entityColumn.isId();if (isPrimaryKey) {pkEntityColumn = entityColumn;break;}}for (EntityColumn entityColumn : columns) {boolean isPrimaryKey = entityColumn.isId();//6.判断当前字段是否为主键if (!isPrimaryKey) {//7.使用非主键字段拼接SET子句String columnHolder = entityColumn.getColumnHolder("item");sb.append("<trim prefix=\"").append(entityColumn.getColumn()).append("= case\" suffix=\"end, \">");sb.append("<foreach collection=\"list\" index=\"index\" item=\"item\">");sb.append(" when ").append(pkEntityColumn.getColumn()).append(" = ").append(pkEntityColumn.getColumnHolder("item")).append(" then ").append(columnHolder);sb.append("</foreach>");sb.append("</trim>");}}sb.append("</trim>");//10.使用前面缓存的主键名、主键值拼接where子句sb.append("where ").append(pkEntityColumn.getColumn()).append(" in ");sb.append("<foreach close=\")\" collection=\"list\" item=\"item\" open=\"(\" separator=\", \">");sb.append(" #{item.").append(pkEntityColumn.getProperty()).append("}");sb.append("</foreach>");//11.将拼接好的字符串返回return sb.toString();}}
选择性批量更新
- Mapper接口
@RegisterMapper
public interface BatchUpdateSelectiveByIdMapper<T> {/*** 选择性批量更新* @param list* @return*/@UpdateProvider(type = BatchUpdateSelectiveByIdProvider.class, method = "dynamicSQL")int batchUpdateSelective(List<T> list);
}
- provider
public class BatchUpdateSelectiveByIdProvider extends MapperTemplate {public BatchUpdateSelectiveByIdProvider(Class<?> mapperClass, MapperHelper mapperHelper) {super(mapperClass, mapperHelper);}/*** 批量更新* @param statement* @return*/public String batchUpdateSelective(MappedStatement statement) {//1.获取实体类对应的Class对象Class<?> entityClass = super.getEntityClass(statement);//2.获取实体类在数据库中对应的表名String tableName = super.tableName(entityClass);//3.生成update子句String update = SqlHelper.updateTable(entityClass, tableName);//4.创建StringBuilder用于拼接SQL语句的各个组成部分StringBuilder sb = new StringBuilder(update);sb.append("<trim prefix=\"set\" suffixOverrides=\",\">");//5.获取所有字段信息Set<EntityColumn> columns = EntityHelper.getColumns(entityClass);//获取主键EntityColumn pkEntityColumn = null;for (EntityColumn entityColumn : columns) {boolean isPrimaryKey = entityColumn.isId();if (isPrimaryKey) {pkEntityColumn = entityColumn;break;}}for (EntityColumn entityColumn : columns) {boolean isPrimaryKey = entityColumn.isId();//6.判断当前字段是否为主键if (!isPrimaryKey) {//7.使用非主键字段拼接SET子句String columnHolder = entityColumn.getColumnHolder("item");sb.append("<trim prefix=\"").append(entityColumn.getColumn()).append("= case\" suffix=\"end, \">");sb.append("<foreach collection=\"list\" index=\"index\" item=\"item\">");sb.append("<if test=\"item.").append(entityColumn.getProperty()).append(" != null\"> ");sb.append(" when ").append(pkEntityColumn.getColumn()).append(" = ").append(pkEntityColumn.getColumnHolder("item")).append(" then ").append(columnHolder);sb.append(" </if>");sb.append("</foreach>");sb.append("</trim>");}}sb.append("</trim>");//10.使用前面缓存的主键名、主键值拼接where子句sb.append("where ").append(pkEntityColumn.getColumn()).append(" in ");sb.append("<foreach close=\")\" collection=\"list\" item=\"item\" open=\"(\" separator=\", \">");sb.append(" #{item.").append(pkEntityColumn.getProperty()).append("}");sb.append("</foreach>");//11.将拼接好的字符串返回return sb.toString();}}
测试代码
@Test
void batchUpdate(){List<Subject> list = List.of(Subject.builder().id(13L).name("111").build(),Subject.builder().id(14L).name("222").build(),Subject.builder().id(15L).name("333").build(),Subject.builder().id(16L).name("444").build());subjectMapper.batchUpdateSelective(list);
}
相关文章:
![](https://www.ngui.cc/images/no-images.jpg)
【精品】通用Mapper 批量更新bug解决方案
问题描述 环境:mysql8.xmybatis3.5.13tk.mybatis4.2.3 在使用tk.mybatis做批量更新时,程序会报错,说是执行的SQL语法错误,经研究源代码发现tk.mybatis在实现批量更新时是通过多次执行update语句实现的。这本身就不符合MySQL批量…...
![](https://img-blog.csdnimg.cn/img_convert/e0fe9c14d11c98856f367dd9fc3caf95.png)
腾讯mini项目-【指标监控服务重构-会议记录】2023-07-06
7/6 会议记录 Profile4个步骤 解压kafka消息初始化性能事件,分析事件将数据写入kafkaRun 开始执行各stage handler 上报耗时到otel-collector。。。 // ConsumerDispatchHandler consumer // // param msg *sarama.ConsumerMessage // param consumer *databus.K…...
![](https://www.ngui.cc/images/no-images.jpg)
【React】函数式组件和类式组件的用法和逻辑
组件的使用 当应用是以多组件的方式实现,这个应用就是一个组件化的应用 注意: 组件名必须是首字母大写虚拟DOM元素只能有一个根元素虚拟DOM元素必须有结束标签 < /> 渲染类组件标签的基本流程React 内部会创建组件实例对象调用render()得到虚拟 …...
![](https://www.ngui.cc/images/no-images.jpg)
题目 1061: 二级C语言-计负均正
从键盘输入任意20个整型数,统计其中的负数个数并求所有正数的平均值。 保留两位小数 样例输入 1 2 3 4 5 6 7 8 9 10 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 样例输出 10 5.50 解题思路: 如题所示,输入20个正负数,---》求付数的个…...
![](https://www.ngui.cc/images/no-images.jpg)
数位和(C++)
系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…...
![](https://img-blog.csdnimg.cn/fb96e6a97ebe4f428df1e485904e9a62.png)
[牛客复盘] 牛客周赛round13 20230924
[牛客复盘] 牛客周赛round13 20230924 总结矩阵转置置2. 思路分析3. 代码实现 小红买基金1. 题目描述2. 思路分析3. 代码实现 小红的密码修改1. 题目描述2. 思路分析3. 代码实现 小红的转账设置方式1. 题目描述2. 思路分析3. 代码实现 小红打boss1. 题目描述2. 思路分析3. 代码…...
![](https://img-blog.csdnimg.cn/1df7c30a92db4dc68b77bf679a1e8eab.png)
mybatsi-MyBatis的逆向工程
mybatsi-MyBatis的逆向工程 一、前言二、创建逆向工程的步骤1.添加依赖和插件2.创建MyBatis的核心配置文件3.创建逆向工程的配置文件4.执行MBG插件的generate目标 一、前言 正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。 Hibernate是支…...
![](https://img-blog.csdnimg.cn/175095f40ea04403a8744034fa35bd1f.jpeg)
转转闲鱼交易猫链接源码 支持二维码收款
最新仿二手闲置链接源码 后台一键生成链接,后台管理教程:解压源码,修改数据库config/Congig 不会可以看源码里有教程 下载程序:https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3...
![](https://img-blog.csdnimg.cn/c72789ccf98543429cfce933a34bd293.png)
Python爬虫基础(三):使用Selenium动态加载网页
文章目录 系列文章索引一、Selenium简介1、什么是selenium?2、为什么使用selenium3、安装selenium(1)谷歌浏览器驱动下载安装(2)安装selenium 二、Selenium使用1、简单使用2、元素定位3、获取元素信息4、交互 三、Phan…...
![](https://img-blog.csdnimg.cn/58cd8b645b214c1d83e276d191768287.png)
Linux系统下安装Mysql
1、执行命令:rpm -qa | grep -i mysql,先查看系统之前是否有安装相关的rpm包,如果有,会显示类似下面的信息; 2、通过命令yum -y remove mysql-* 一次性删除系统上所有相关的rpm包,或者通过命令yum -y …...
![](https://img-blog.csdnimg.cn/55cb22d4ac11458d9ec2f7a07fc9cb0f.png)
Jenkins学习笔记1
CI 服务器: 认识Jenkins: Jenkins是一个可扩展的持续集成(CI)引擎,是一个开源项目,旨在提供一个开放易用的软件平台,使得软件持续集成变成可能。Jenkins非常易于安装和配置,简单易…...
![](https://www.ngui.cc/images/no-images.jpg)
注意力机制
概念没什么好说的,反正大家都会说,具体实战怎么写才是最为重要的 1.自注意力 假设有一组数据,都是一维的向量,这个向量可能是一个样本,可能是其他什么,都无所谓。 假设有一组一维向量x1,x2,x3,x4,x5; 第…...
![](https://www.ngui.cc/images/no-images.jpg)
JVM-Java字节码技术笔记
Java字节码技术 Java字节码是java代码编译后的中间代码格式,JVM需要读取并解析字节码才能执行相应的任务 获取字节码简介:由单字节(byte)的指令组成 操作码( 指令), 主要由类型前缀和操作名称两部分组成。根据指令的性质…...
![](https://img-blog.csdnimg.cn/img_convert/0ededa294f5eae625d47d2132e8affeb.png)
C++ 友元、重载、继承、多态
友元 关键字:friend 友元的三种实现 全局函数做友元类做友元成员函数做友元 全局函数做友元 //建筑物类 class Building {//goodGay全局函数是Building好朋友,可以访问Building中私有成员friend void goodGay(Building& building); public:Build…...
![](https://img-blog.csdnimg.cn/ee26fc2ab5a44c59b1ff0d49ed96acd6.png)
Spring Boot 日志文件
前言 本篇博客主要介绍自定义的日志打印、日志的级别高低、如何保存日志等等..... 一、日志是什么?日志有什么用? 日志就是我们控制台上输出的内容,控制台上的输出的信息就是日志信息,如下所示: 日志有什么用&#x…...
![](https://img-blog.csdnimg.cn/e62ba10bb51a4b4b8953952d8bb03dc6.png)
vulhub venom
文章目录 靶场环境信息收集ftp服务二、信息利用三、任意文件上传三 sudo提权靶场环境 `vmware 靶场信息:https://www.vulnhub.com/entry/venom-1,701/ 下载地址:https://download.vulnhub.com/venom/venom.zip 新建虚拟机打开下载后的ovf文件 遇见导入失败合规性检查时,重试…...
![](https://www.ngui.cc/images/no-images.jpg)
量化交易之One Piece篇 - linux - 定时任务(重启服务器、执行程序、验证)
linux 执行命令: crontab -e 0 5 * * 1-5 sudo /sbin/shutdown -r now 0 17 * * 1-5 sudo /sbin/shutdown -r now 45 8 * * 1-5 cd /home/ubuntu/onepiece/bin/datacore && ./datacore 45 20 * * 1-5 cd /home/ubuntu/onepiece/bin/datacore && ./datacore 以…...
![](https://img-blog.csdnimg.cn/85ae9415e0364dda8f545b86380c4479.png)
Qt5开发及实例V2.0-第二十三章-Qt-多功能文档查看器实例
Qt5开发及实例V2.0-第二十三章-Qt-多功能文档查看器实例 第23章 多功能文档查看器实例23.1. 简介23.2. 界面与程序框架设计23.2.1. 图片资源23.2.2. 网页资源23.2.3. 测试用文件 23.3 主程序代码框架23.4 浏览网页功能实现23.4.1 实现HtmIHandler处理器 23.5. 部分代码实现23.5…...
![](https://img-blog.csdnimg.cn/0858e8abc4504e75b870b156806d9299.png)
爬虫笔记_
爬虫简介 爬虫初始深入 爬虫在使用场景中的分类 通用爬虫: 抓取系统重要组成部分。抓取的是一整张页面数据 聚焦爬虫: 是建立在通用爬虫的基础上。抓取的是页面中特定的局部内容。 增量式爬虫 监测网站中数据更新的情况。只会抓取网站中最新更新出来的…...
![](https://www.ngui.cc/images/no-images.jpg)
Spring设计模式,事务管理和代理模式的应用
扩充:贝叶斯定理答案见底。 设计模式对关于面向对象问题的具体解决方案. 1,单例多例 在设计单例模式时,要注意两个点 1.构造方法要私有 2.成员变量要私有 3.创建对象所用的方法要被synchronized修饰.(因为方法体中会涉及到判断当…...
![](https://img-blog.csdnimg.cn/d094b90c00c6436e825d2a2ec5f342b7.png)
基于海康Ehome/ISUP接入到LiveNVR实现海康摄像头、录像机视频统一汇聚,做到物联网无插件直播回放和控制
LiveNVR支持海康NVR摄像头通EHOME接入ISUP接入LiveNVR分发视频流或是转GB28181 1、海康 ISUP 接入配置2、海康设备接入2.1、海康EHOME接入配置示例2.2、海康ISUP接入配置示例 3、通道配置3.1、直播流接入类型 海康ISUP3.2、海康 ISUP 设备ID3.3、启用保存3.4、接入成功 4、相关…...
![](https://img-blog.csdnimg.cn/img_convert/b453ac0abc352973476e881bdac679d3.png)
Linux下git安装及使用
Linux下Git使用 1. git的安装 sudo apt install git安装完,使用git --version查看git版本 2. 配置git git config --global user.name "Your Name“ ##配置用户 git config --global user.email emailexample.com ##配置邮箱git config --global --list …...
![](https://www.ngui.cc/images/no-images.jpg)
python读取图片
要在Python中读取图片,你可以使用第三方库Pillow(Python Imaging Library,PIL)或OpenCV。以下是使用这两个库的示例: 使用Pillow库读取图片: 首先,确保你已经安装了Pillow库。如果还没有安装&am…...
![](https://img-blog.csdnimg.cn/d526fba227d54e9aae596dc4538545d4.png)
虚幻4学习笔记(15)读档 和存档 的实现
虚幻4学习笔记 读档存档 B站UP谌嘉诚课程:https://www.bilibili.com/video/BV164411Y732 读档 添加UI蓝图 SaveGame_UMG 添加Scroll Box 修改Scrollbar Thickness滚动条厚度 15 15 勾选 is variable 添加text 读档界面 添加背景模糊 添加UI蓝图 SaveGame_Slot …...
![](https://img-blog.csdnimg.cn/de64e8502aae4bf98af20d69c8f2e6ba.png)
Spring面试题22:Spring支持哪些ORM框架?优缺点分别是什么?Spring可以通过哪些方式访问Hibernate?
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Spring支持哪些ORM框架?优缺点分别是什么? Spring 支持多种 ORM(对象关系映射)框架,其中包括: Hibernate:Hibernate 是一个强大的 ORM 框架…...
![](https://www.ngui.cc/images/no-images.jpg)
流行的Python库numpy及Pandas简要介绍
numpy.ndarray 是NumPy库中的主要数据结构,它是一个多维数组,用于存储和操作数值数据。NumPy是Python中用于数值计算的强大库,numpy.ndarray 是它的核心数据类型,提供了高效的数值运算和广泛的数学函数。 以下是 numpy.ndarray 的…...
![](https://img-blog.csdnimg.cn/94c4d587e68a4f98b5983b55aeceb69d.png)
【二、安装centOS】
下载 地址:https://mirrors.aliyun.com/centos/ 地址 1、https://mirrors.aliyun.com/centos/7.9.2009/ 2、https://mirrors.aliyun.com/centos/7.9.2009/isos/ 3、https://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/ 选哪一个 可以选择第一个࿰…...
![](https://img-blog.csdnimg.cn/510bed509116437c8420150908426bfb.png)
【动手学深度学习-Pytorch版】序列到序列的学习(包含NLP常用的Mask技巧)
序言 这一节是对于“编码器-解码器”模型的实际应用,编码器和解码器架构可以使用长度可变的序列作为输入,并将其转换为固定形状的隐状态(编码器实现)。本小节将使用“fra-eng”数据集(这也是《动手学习深度学习-Pytor…...
![](https://img-blog.csdnimg.cn/7d5ed9143531462da9d6a8c10d000ffe.png)
AUTOSAR 面试知识回顾
如果答不上来,就讲当时做了什么 1. Ethernet基础: 硬件接口: ECU到PHY: data 是MII总线, 寄存器控制是SMI总线【MDCMDIO两根线, half duplex】PHY输出(100BASE-T1): MDI总线,2 wire 【T1: twisted 1 pair …...
![](https://img-blog.csdnimg.cn/7b9356a544d84947a6f7016710012f8f.png)
华为NFC设置教程(门禁卡/公交卡/校园卡等)
今天把华为NFC设置教程分享给大家 出门带门禁卡、校园卡、银行卡、身份证……东西又多,携带又麻烦,还容易搞丢,有没有一种方法可以把它们都装下?有!只要一部手机,出门不带卡包,各种证件&#x…...
![](/images/no-images.jpg)
易语言可以做网站后端/央视新闻
docker私服搭建有官方的registry镜像,也有改版后的NexusOss3.x,因为maven的原因搭建了nexus,所以一并将docker私服也搭建到nexus上。 nexus的安装过程就单独说了,如果是2.x系列需要升级到2.14版本再升级到3.y系列,如果…...
![](/images/no-images.jpg)
中标公示查询官网/企业网站关键词优化
关于这个坑,我觉得我有必要说一下,太坑了,从晚上弄到早上 所以说,我觉得很有必要讲一下我的想法: 1。我觉得 首先,我要感谢我参考的两篇博客,给了我很大的帮助。 https://blog.csdn.net/qq_…...
![](https://img-blog.csdnimg.cn/2574b4710683451b93505baff1dcb24a.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqW5LuU5Lya6aOe,size_20,color_FFFFFF,t_70,g_se,x_16)
网站备案到期了怎么办/网站需要怎么优化比较好
文章目录类适配器代码对象适配器代码类适配器 SDCard 是一个接口,代表了 SD 卡本身具有的功能SDCardImpl 是一个具体的实现类,代表了 SDCard 一种具体的实现形式TFCard 是一个接口,代表了 TF 卡本身具有的功能TFCardImpl 是一个具体的实现类…...
![](/images/no-images.jpg)
武汉网站设计师培训学校/淘宝运营培训班
计算机软硬件实训报告汇编新疆大学实习(实训)报告实习(实训)名称: 计算机软硬件工程实践学 院: 电气工程学院专 业、 班 级: 电气15-3指 导 教 师: 蔺红 娄毅报 告 人: 赵泽明学 号: 20152101202时 间&…...
![](https://img-blog.csdnimg.cn/img_convert/e89b78243db714b0f1140f236946f70f.png)
软件源码购买一般在哪个网站/保定网站推广公司
描述:LM2776DBVRLM2776 CMOS电容泵电压转换器可将2.7V至5.5V范围内的正电压转换,从而获得对应的等值负电压。 电感的转换器,解决了成本,尺寸和电磁干扰(EMI)多方面问题。在大多数负载条件下,LM2776的工作电流仅为100μ…...
![](/images/no-images.jpg)
个人备案能做公司网站吗/邀请注册推广赚钱的app
忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2021-06-04 ❤️❤️ 本篇更新记录 2022-01-21 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请…...