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

mybatis批量插入、mybatis-plus批量插入、mybatis实现insertList、mybatis自定义实现批量插入

文章目录

  • 一、mybatis新增批量插入
    • 1.1、引入依赖
    • 1.2、自定义通用批量插入Mapper
    • 1.3、把通用方法注册到mybatisplus注入器中
    • 1.4、实现InsertList类
    • 1.5、需要批量插入的dao层继承批量插入Mapper
  • 二、可能遇到的问题
    • 2.1、Invalid bound statement

众所周知,mybatisplus提供的BaseMapper里只有单条插入的方法,没有批量插入的方法,
而在Service层的批量插入并不是真的批量插入,实际上是遍历insert,但也不是一次insert就一次IO,而是到一定数量才会去IO一次,性能不是很差,但也不够好。

怎么才能实现真正的批量插入呢?

这里是mybatisplus官方的演示仓库,可以先去了解一下。

一、mybatis新增批量插入

1.1、引入依赖

本文基于mybatis-plus3.5.0进行讲解,不同的版本写法稍微有点不同。

<!--mybatis-plus-->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.0</version></dependency>

1.2、自定义通用批量插入Mapper

1.新建一个InsertListMapper文件,提供insertList方法,后续需要用到批量插入的dao继承该Mapper即可拥有批量插入接口。

import org.apache.ibatis.annotations.Param;
import java.util.List;/*** 通用Mapper接口,特殊方法,批量插入,支持批量插入的数据库都可以使用,例如mysql,h2等** @param <T> 不能为空* @author*/
public interface InsertListMapper<T> {/*** 批量插入,支持批量插入的数据库可以使用,例如MySQL,H2等* <p>* 注意:* 1.若实体类中设置了@TableId注解,则需要设置value值  如:@TableId(value = "id")* 2.若建表语句中设置了default, 需要在插入时手动设置默认值,否则存储的是null。* 如:delete_flag tinyint default 0 comment '删除标志 0-未删除 1-已删除',这种需要在insert的时候设置实体类改字段值。setDeleteFlag(0)* <p>** @param recordList* @return*/int insertList(@Param("list") List<T> recordList);
}

1.3、把通用方法注册到mybatisplus注入器中

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.springframework.stereotype.Component;import java.util.List;/*** 添加Sql注入方法,支持空字段更新*/
@Component
public class CustomerSqlInjector extends DefaultSqlInjector {@Overridepublic List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo){List<AbstractMethod> methodList=super.getMethodList(mapperClass, tableInfo);//注册自定义方法//注意:InsertList中的name需要与xxxMapper中的方法名一致,即insertListmethodList.add(new InsertList("insertList"));return methodList;}
}

关键的一句在于methodList.add(new InsertList("insertList"));,意为注册一个新的方法叫insertList,具体实现在InsertList类。

1.4、实现InsertList类

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import java.util.Collections;public class InsertList extends AbstractMethod {public InsertList(String name) {super(name);}@Overridepublic MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {KeyGenerator keyGenerator = new NoKeyGenerator();SqlSource sqlSource = languageDriver.createSqlSource(configuration, getBatchInsertSql(tableInfo,modelClass), Collections.class);return this.addInsertMappedStatement(mapperClass,modelClass,"insertList",sqlSource,keyGenerator,null,null);}private String getBatchInsertSql(TableInfo tableInfo, Class<?> modelClass){String batchInsertSql="<script> INSERT INTO %s (%s) values %s</script>";//要插入的字段 即insert into table(要插入的字段) valuesStringBuilder insertColumnSql=new StringBuilder();insertColumnSql.append(tableInfo.getKeyColumn()).append(",");StringBuilder valueSql=new StringBuilder();valueSql.append("<foreach collection='list' item='item' open='(' separator='),(' close=')' >\n");valueSql.append("#{item."+tableInfo.getKeyProperty()+"},");tableInfo.getFieldList().forEach(x->{insertColumnSql.append(x.getColumn()).append(",");valueSql.append("#{item."+x.getProperty()+"},");});insertColumnSql.delete(insertColumnSql.length()-1,insertColumnSql.length());valueSql.delete(valueSql.length()-1,valueSql.length());valueSql.append("</foreach>");return  String.format(batchInsertSql,tableInfo.getTableName(),insertColumnSql,valueSql);}}

1.5、需要批量插入的dao层继承批量插入Mapper

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.demo.common.mapper.InsertListMapper;
import com.demo.entity.User;/**
* @Entity generator.domain.User
*/
public interface UserMapper extends BaseMapper<User>, InsertListMapper<User> {}

以上代码全都放在gitee仓库,详情见:
代码仓库地址

二、可能遇到的问题

2.1、Invalid bound statement

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.demo.mapper.User1Mapper.insertListat org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.<init>(MybatisMapperMethod.java:50)at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.lambda$cachedInvoker$0(MybatisMapperProxy.java:111)at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)at com.baomidou.mybatisplus.core.toolkit.CollectionUtils.computeIfAbsent(CollectionUtils.java:115)at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.cachedInvoker(MybatisMapperProxy.java:98)at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)at com.sun.proxy.$Proxy70.insertList(Unknown Source)at com.demo.User1Test.test1(User1Test.java:50)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

解决方法: :https://blog.csdn.net/weixin_49114503/article/details/140645048







参考文章:https://blog.csdn.net/m0_51390969/article/details/134730527
https://blog.csdn.net/m0_63297646/article/details/131843517

相关文章:

mybatis批量插入、mybatis-plus批量插入、mybatis实现insertList、mybatis自定义实现批量插入

文章目录 一、mybatis新增批量插入1.1、引入依赖1.2、自定义通用批量插入Mapper1.3、把通用方法注册到mybatisplus注入器中1.4、实现InsertList类1.5、需要批量插入的dao层继承批量插入Mapper 二、可能遇到的问题2.1、Invalid bound statement 众所周知&#xff0c;mybatisplus…...

Springboot项目的行为验证码AJ-Captcha(源码解读)

目录 前言1. 复用验证码2. 源码解读2.1 先走DefaultCaptchaServiceImpl类2.2 核心ClickWordCaptchaServiceImpl类 3. 具体使用 前言 对于Java的基本知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;【Java项目…...

【初阶数据结构篇】时间(空间)复杂度

文章目录 算法复杂度时间复杂度1. 定义2. 表示方法3. 常见时间复杂度4.案例计算分析冒泡排序二分查找斐波那契数列&#xff08;递归法&#xff09;斐波那契数列&#xff08;迭代法&#xff09; 空间复杂度案例分析冒泡排序斐波那契数列&#xff08;递归法&#xff09;斐波那契数…...

C# 设计模式分类

栏目总目录 1. 创建型模式&#xff08;Creational Patterns&#xff09; 创建型模式主要关注对象的创建过程&#xff0c;包括如何实例化对象&#xff0c;并隐藏实例化的细节。 单例模式&#xff08;Singleton&#xff09;&#xff1a;确保一个类只有一个实例&#xff0c;并提…...

前端模块化CommonJS、AMD、CMD、ES6

在前端开发中&#xff0c;模块化是一种重要的代码组织方式&#xff0c;它有助于将复杂的代码拆分成可管理的小块&#xff0c;提高代码的可维护性和可重用性。CommonJS、AMD&#xff08;异步模块定义&#xff09;和CMD&#xff08;通用模块定义&#xff09;是三种不同的模块规范…...

论文阅读:(DETR)End-to-End Object Detection with Transformers

论文阅读&#xff1a;&#xff08;DETR&#xff09;End-to-End Object Detection with Transformers 参考解读&#xff1a; 论文翻译&#xff1a;End-to-End Object Detection with Transformers&#xff08;DETR&#xff09;[已完结] - 怪盗kid的文章 - 知乎 指示函数&…...

react中路由跳转以及路由传参

一、路由跳转 1.安装插件 npm install react-router-dom 2.路由配置 路由配置&#xff1a;react中简单的配置路由-CSDN博客 3.实现代码 // src/page/index/index.js// 引入 import { Link, useNavigate } from "react-router-dom";function IndexPage() {const …...

C++ STL set_symmetric_difference

一&#xff1a;功能 给定两个集合A&#xff0c;B&#xff1b;求出两个集合的对称差&#xff08;只属于其中一个集合&#xff0c;而不属于另一个集合的元素&#xff09;&#xff0c;即去除那些同时在A&#xff0c;B中出现的元素。 二&#xff1a;用法 #include <vector>…...

postman请求响应加解密

部分接口&#xff0c;需要请求加密后&#xff0c;在发动到后端。同时后端返回的响应内容&#xff0c;也是经过了加密。此时&#xff0c;我们先和开发获取到对应的【密钥】&#xff0c;然后在postman的预执行、后执行加入js脚本对明文请求进行加密&#xff0c;然后在发送请求&am…...

数据集,批量更新分类数值OR批量删除分类行数据

数据集批量更新分类OR删除分类行数据 import osdef remove_class_from_file(file_path, class_to_remove):"""从YOLO格式的标注文件中删除指定类别的行记录&#xff0c;并去除空行。:param file_path: YOLO标注文件路径:param class_to_remove: 需要删除的类别…...

一款功能强大的视频编辑软件会声会影2023

会声会影2023是一款功能强大的视频编辑软件&#xff0c;由加拿大Corel公司制作&#xff0c;正版英文名称为‌Corel VideoStudio。它具备图像抓取和编修功能&#xff0c;可以处理和转换多种视频格式&#xff0c;如‌MV、‌DV、‌V8、‌TV和实时记录抓取画面文件。会声会影提供了…...

政安晨【零基础玩转各类开源AI项目】基于Ubuntu系统部署LivePortrait :通过缝合和重定向控制实现高效的肖像动画制作

目录 项目论文介绍 论文中实际开展的工作 非扩散性的肖像动画 基于扩散的肖像动画 方法论 基于Ubuntu的部署实践开始 1. 克隆代码并准备环境 2. 下载预训练权重 3. 推理 快速上手 驱动视频自动裁剪 运动模板制作 4. Gradio 界面 5. 推理速度评估 社区资源 政安…...

在Spring项目中使用Maven和BCrypt来实现修改密码功能

简介 在数字时代&#xff0c;信息安全的重要性不言而喻&#xff0c;尤其当涉及到个人隐私和账户安全时。每天&#xff0c;无数的用户登录各种在线服务&#xff0c;从社交媒体到银行账户&#xff0c;再到电子邮件和云存储服务。这些服务的背后&#xff0c;是复杂的系统架构&am…...

RedHat8安装Oracle19C

RedHat8安装Oracle19C 1、 更新yum源 更新yum源为阿里云镜像源&#xff1a; # 进入源目录 cd /etc/yum.repos.d/ # 删除 redhat 默认源 rm redhat.repo # 下载阿里云的centos7源 curl -O http://mirrors.aliyun.com/repo/Centos-8.repo # 替换 Centos-8.repo 中的 $releasev…...

React系列面试题

大家好&#xff0c;我是有用就点赞&#xff0c;有用就扩散。 1.React的组件间通信都有哪些形式&#xff1f; 父传子&#xff1a;在React中&#xff0c;父组件调用子组件时可以将要传递给子组件的数据添加在子组件的属性中&#xff0c;在子组件中通过props属性进行接收。这个就…...

C#:通用方法总结—第6集

大家好&#xff0c;今天继续介绍我们的通用方法系列。 下面是今天要介绍的通用方法&#xff1a; &#xff08;1&#xff09;这个通用方法为SW查找草图数量 /// <summary> /// 查找草图数量 /// </summary> /// <param name"doc2"></param>…...

Spark实时(一):StructuredStreaming 介绍

文章目录 Structured Streaming 介绍 一、SparkStreaming实时数据处理痛点 1、复杂的编程模式 2、SparkStreaming处理实时数据只支持Processing Time 3、微批处理,延迟高 4、精准消费一次问题 二、StructuredStreaming架构与场景应用 三、​​​​​​​​​​​​​​…...

LangChain4j-RAG基础

RAG是什么 简而言之&#xff0c;RAG 是一种在将数据发送到 LLM 之前从数据中查找相关信息并将其注入到提示中的方法。这样LLM将获得&#xff08;希望&#xff09;相关信息&#xff0c;并能够使用这些信息进行回复&#xff0c;这应该会减少产生幻觉的可能性。 实现方法: 全文…...

git--本地仓库修改同步到远程仓库

尝试将本地分支推送到远程仓库时&#xff0c;出现一个非快速前进的错误。通常是因为远程仓库中的分支包含本地分支没有的提交。在推送之前&#xff0c;需要将远程仓库的更改合并到本地分支。 解决步骤如下&#xff1a; 切换到你的本地分支&#xff1a; 确保处于想要推送的分支…...

剑和沙盒 3 - 深度使用和解析Windows Sandbox

介绍 两年前&#xff0c;微软作为Insiders build 18305的一部分发布了一项新功能- Windows Sandbox。 该沙箱具有一些有用的规格&#xff1a; Windows 10&#xff08;Pro/Enterprise&#xff09;的集成部分。在 Hyper-V 虚拟化上运行。原始且可抛弃 – 每次运行时都干净地开…...

ChatGPT 2026不是升级,是重构:Transformer-XL²架构、128K动态上下文、本地化模型热插拔——你还在用2023版?这5个信号说明你已被淘汰

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;ChatGPT 2026&#xff1a;一场从架构内核出发的范式革命 ChatGPT 2026 并非简单的能力叠加&#xff0c;而是以「动态稀疏混合专家&#xff08;Dynamic Sparse MoE&#xff09;」为核心重构推理路径&…...

保障线上服务高可用借助 Taotoken 的容灾与路由能力

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 保障线上服务高可用借助 Taotoken 的容灾与路由能力 对于依赖大模型 API 的线上应用而言&#xff0c;服务的持续可用性是核心诉求之…...

员工管理(新增员工)、事务管理和文件上传(阿里云OSS)

员工管理(新增员工) 思路就是就是新增的员工基本信息和批量保存员工的工作经历信息&#xff0c;也就是后端对应了两条sql语句&#xff0c; 1.保存员工基本信息 Emp实体类中新添一个字段用于保存员工工作经历 //封装工作经历 private List<EmpExpr> exprList; (1)Cont…...

【DSP学习】外部中断实验-基于普中DSP28335开发攻略

参考材料 普中DSP28335开发攻略 一、外部中断配置 1 失能 CPU 级中断&#xff0c;并初始化 PIE 控制器寄存器和 PIE 中断向量表在前面学习中断章节中&#xff0c;我们知道 F28335 的外设中断需通过 PIE 控制器来管理&#xff0c;因此需要初始化 PIE 相应的寄存器和中断向量表。…...

通过API Key管理与审计日志功能增强企业AI应用安全

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 通过API Key管理与审计日志功能增强企业AI应用安全 在将大模型能力集成到企业业务流程时&#xff0c;安全与合规是首要考量。直接使…...

如何用OBS插件打造专业音乐直播?Tuna插件完整指南

如何用OBS插件打造专业音乐直播&#xff1f;Tuna插件完整指南 【免费下载链接】tuna Song information plugin for obs-studio 项目地址: https://gitcode.com/gh_mirrors/tuna1/tuna 想让你的OBS直播画面瞬间升级为专业音乐电台风格吗&#xff1f;Tuna插件正是你需要的…...

AI模型评估资源精选:从标准基准到定制化实践指南

1. 项目概述&#xff1a;为什么我们需要一个AI评估资源精选集&#xff1f;如果你最近也在折腾大语言模型&#xff0c;无论是想自己微调一个&#xff0c;还是想评估市面上哪个模型更适合你的业务场景&#xff0c;大概率会遇到一个头疼的问题&#xff1a;评估标准太多了&#xff…...

FastDFS整合Nginx踩坑记:升级1.22.0修复CVE-2021-23017,如何平滑保留模块不报错?

FastDFS整合Nginx安全升级实战&#xff1a;从漏洞修复到模块兼容的全流程指南 最近在维护一个使用FastDFS作为分布式存储的生产环境时&#xff0c;遇到了Nginx的CVE-2021-23017安全漏洞问题。这个漏洞可能允许攻击者通过特制的DNS响应导致工作进程崩溃&#xff0c;对于线上业务…...

学术人必抢的实时检索红利,Perplexity这4个隐藏功能90%研究者至今未启用,错过再等半年!

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Perplexity实时学术搜索怎么用 Perplexity 是一款面向研究者与开发者设计的实时学术搜索引擎&#xff0c;其核心优势在于直接对接 arXiv、PubMed、ACL Anthology、Semantic Scholar 等权威学术数据库&a…...

AI产品技能库:将顶尖产品智慧注入Claude Code的实战指南

1. 项目概述&#xff1a;当AI助手遇上产品大师的智慧如果你是一名产品经理、创业者&#xff0c;或者任何需要与产品打交道的人&#xff0c;最近可能已经感受到了AI助手带来的效率革命。无论是用Claude Code写代码&#xff0c;还是用ChatGPT梳理思路&#xff0c;这些工具正在成为…...