[精] MySQL和Oracle下Mybatis批量操作示例和获取影响行数介绍

news2024/9/21 14:04:42

手打不易,如果转摘,请注明出处!

注明原文:https://zhangxiaofan.blog.csdn.net/article/details/117933877


目录

前言

Mybatis 执行器

 表结构定义

Mybatis批量新增

批量新增——Mysql写法

批量新增——Oracle写法

Mybatis批量删除

批量删除——MySQL写法、Oracle写法一样

Mybatis批量更新

批量更新——MySQL写法

批量更新——Oracle写法

总结


前言

本文将以示例的方式,介绍Mybatsi批量操作增删改,以及如何获取影响行数,涉及到MySQL和Oracle两种不同的写法。

Mybatis 执行器

Mybatis 执行器三种模式介绍

default-executor-type:
simple(默认): 
    SimpleExecutor, 单个 sqlsession 内, 每次操作,都开启一个 Statement 对象,用完立刻关闭 Statement 对象
batch: 
    BatchExecutor, 单个 sqlsession 内,每次操作复用已有 Statement 对象, addBatch()汇总,然后统一执行executeBatch()
    因此 Mybatis 官方写明它无法返回行数(BATCH executor is in use, the update counts are being lost.)
reuse: 
    ReuseExecutor, 应用实例内, 全局共享 Statement对象(Map<String, Statement>), 存在则复用

 表结构定义

CREATE TABLE `student`
(
    `id`   int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
    `age`  int(11)      DEFAULT NULL,
    PRIMARY KEY (`id`)
)
ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci;

Mybatis批量新增

一般批量insert有4种写法
1.循环插入,每次插入一条,用的不多,这里不介绍

注意:如果是一次提交多个insert/update语句,MySQL的连接串需要加上
allowMultiQueries=true,表示开启批处理,可以执行批量SQL。就是多个分号;的SQL

2.BEGIN-END写法,这个是单次多条insert语句,用的不多,这里不介绍
3.foreach写法,这个是单次单条insert语句(常用)
4.JDBC原生写法,这个效率最高,不属于mybatis写法,这里不介绍

Mapper接口定义:

int insertListBatch(@Param("studentList") List<Student> studentList);

批量新增——Mysql写法

单次单条insert语句,foreach-batch写法

    <insert id="insertListBatch">
        insert into student(
        id,
        name,
        age
        ) values
        <foreach collection="studentList" item="item" index="index" separator=",">
            (
            #{item.id,jdbcType=INTEGER},
            #{item.name,jdbcType=VARCHAR},
            #{item.age,jdbcType=INTEGER}
            )
        </foreach>
    </insert>

获取返回影响行数,只需要用下面这种执行器模式,直接获取返回值,该值就是影响行数。Oracle也是一样。

default-executor-type: simple
        int i = studentService.insertListBatch(studentList);
        logger.info("Mybatis SQL return :" + i);

批量新增——Oracle写法

单次单条insert语句,foreach-batch写法

    <insert id="insertListBatch">
        insert into STUDENT(
        ID,
        NAME,
        AGE
        )
        <foreach collection="studentList" item="item" index="index" separator="union all">
            (
            select
            #{item.id},
            #{item.name,jdbcType=VARCHAR},
            #{item.age,jdbcType=DECIMAL}
            from dual
            )
        </foreach>
    </insert>

Oracle与MySQL批量插入的区别就是Oracle需要用到 union all 和 dual 关键字,看下Oracle批量插入的SQL示例就知道了:

INSERT INTO TEST.STUDENT (ID,NAME,AGE)
(SELECT 7,'change',18 FROM dual)
UNION ALL
(SELECT 5,'change',18 FROM dual)

上面说到,Mybatis批量插入有几种写法,那么这些写法有什么区别?效率怎么样?可以参考这篇文章:4亿数据批量操作插入,为什么不用Mybatis,而是选择原生JDBC?(文中有各类批量操作效率对比和总结)https://zhangxiaofan.blog.csdn.net/article/details/121351546


Mybatis批量删除

Mapper接口定义

int deleteByIdList(@Param("list") List<String> list);

批量删除——MySQL写法、Oracle写法一样

    <delete id="deleteByIdList">
        delete from student
        where id IN
        <foreach collection="list" item="item" open="(" close=")" separator=",">
            #{item}
        </foreach>
    </delete>

 返回影响行数,跟批量插入一样,用simple(默认)执行器即可,直接获取返回值。

Mybatis批量更新

Mapper接口定义

int updateListByIdBatch(@Param("studentList") List<Student> studentList);

批量更新——MySQL写法

    <update id="updateListByIdBatch">
        update student
        <trim prefix="set" suffixOverrides=",">
            <trim prefix="age =case" suffix="end,">
                <foreach collection="studentList" item="item" index="index">
                    <if test="item.age != null">
                        when id=#{item.id} then #{item.age,jdbcType=INTEGER}
                    </if>
                </foreach>
            </trim>
            <trim prefix="name =case" suffix="end">
                <foreach collection="studentList" item="item" index="index">
                    <if test="item.name != null">
                        when id=#{item.id,jdbcType=INTEGER} then #{item.name,jdbcType=VARCHAR}
                    </if>
                </foreach>
            </trim>
        </trim>
        where id in
        <foreach collection="studentList" item="item" index="index" separator="," open="(" close=")">
            #{item.id,jdbcType=INTEGER}
        </foreach>
    </update>

返回影响行数,跟批量插入一样,用simple(默认)执行器即可,直接获取返回值。 

批量更新——Oracle写法

​
    <update id="updateListByIdBatch">
        update STUDENT
        <trim prefix="set" suffixOverrides=",">
            <trim prefix="AGE =case" suffix="end,">
                <foreach collection="studentList" item="item" index="index">
                    <choose>
                        <when test="item.age != null">
                            when ID=#{item.id} then #{item.age,jdbcType=DECIMAL}
                        </when>
                        <otherwise>
                            <!-- 字段为null, 用原值更新(保留原值), 否则会被重置为null -->
                            when ID=#{item.id,jdbcType=DECIMAL} then age
                        </otherwise>
                    </choose>
                </foreach>
            </trim>
            <trim prefix="NAME =case" suffix="end">
                <foreach collection="studentList" item="item" index="index">
                    <choose>
                        <when test="item.name != null">
                            when ID=#{item.id,jdbcType=DECIMAL} then #{item.name,jdbcType=VARCHAR}
                        </when>
                        <otherwise>
                            <!-- 字段为null, 用原值更新(保留原值), 否则会被重置为null -->
                            when ID=#{item.id,jdbcType=DECIMAL} then name
                        </otherwise>
                    </choose>
                </foreach>
            </trim>
        </trim>
        where ID in
        <foreach collection="studentList" item="item" index="index" separator="," open="(" close=")">
            #{item.id,jdbcType=DECIMAL}
        </foreach>
    </update>​

Oracle与MySQL批量更新的写法主要区别在,Oracle需要用 choose-when-otherwise 来解决部分输入字段为null的问题。感兴趣的朋友可以参考这篇文章:

Oralce Mybaits批量更新的正确写法——解决传入字段为nullhttps://zhangxiaofan.blog.csdn.net/article/details/120179181?spm=1001.2014.3001.5502返回影响行数,跟批量插入一样,用simple(默认)执行器即可,直接获取返回值。

where如果有多个条件,可以写成类似这样的:

        where (ID,ID2) in
        <foreach collection="studentList" item="item" index="index" separator="," open="(" close=")">
            (#{item.id,jdbcType=DECIMAL},#{item.id2,jdbcType=DECIMAL})
        </foreach>

总结

上述Mybatis的批量操作都是一条SQL操作完成的,也是项目中常用到的写法。当一次操作的数据量很大的时候,这种写法效率会大大降低(可能都不如循环一条一条的执行)。因此实际项目过程中批量操作,如果数据较大,就要分批次处理,一次传一部分,具体传多少跟表字段大小和SQL条数相关。

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

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

相关文章

【甄选靶场】Vulnhub百个项目渗透——项目五十四:jarbas-1(类git反弹shell,计划任务提权)

Vulnhub百个项目渗透 Vulnhub百个项目渗透——项目五十四&#xff1a;jarbas-1&#xff08;类git反弹shell,计划任务提权&#xff09; &#x1f525;系列专栏&#xff1a;Vulnhub百个项目渗透 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; …

SpringMvc源码分析(四) 请求执行过程之执行MethodHandler

在上文SpringMvc源码分析&#xff08;三&#xff09;中我们分析了DispatcherServlet类中的doDispatcher方法&#xff0c; 并通过分析方法1和方法2了解了请求执行时是怎么获取MethodHandler链的&#xff0c;本文接上文继续分析方法3、方法4和方法5了解MethodHandler是如何执行的…

springboot rabbitmq 非阻塞重试机制实现

重试的应用场景 比如&#xff0c;系统之间同步数据&#xff0c;A系统发送数据给B系统&#xff0c;因为网络原因或者B系统正在重启&#xff0c;可能收不到信息&#xff0c;为了确保B能收到消息就得重试几次&#xff1b;经典的比如&#xff0c;微信支付回调 对后台通知交互时&am…

VScode远程连接Linux

文章目录一、下载安装二、使用三、连接四、基本操作五、VScode内置命令行六、推荐插件一、下载安装 下载的问题就不用多说了把&#xff0c;可能存在的问题就是下载的速度比较慢 前往官网进行下载&#xff1a;前往官网找到适合自己的版本&#xff1a; 但是由于官网是国外的&am…

DT-6_TTL-WiFi透传模块介绍

DT-6_TTL-WiFi透传模块简介TTL-WiFi模块基于ESP-M2WiFi 模块研发&#xff0c;引出串口TTL、EN、STATE等引脚。产品内置我司最新版本的串口透传固件可完成设备TTL 端口到WiFi/云的数据实时透传&#xff0c;具备低功耗控制&#xff0c;状态指示等功能。本模块可直接取代原有的有线…

【手写 Vue2.x 源码】第三十二篇 - diff算法-乱序比对

一&#xff0c;前言 上篇&#xff0c;diff算法-比对优化&#xff08;下&#xff09;&#xff0c;主要涉及以下几个点&#xff1a; 介绍了儿子节点比较的流程介绍并实现了头头、尾尾、头尾、尾头4种特殊情况比对 本篇&#xff0c;继续介绍 diff算法-乱序比对 二&#xff0c;乱…

MATLAB | 全网最全边际图绘制模板(直方图、小提琴图、箱线图、雨云图、散点图... ...)

如标题所言&#xff0c;这应该是全网最全的边际图绘制模板&#xff0c;中心图有8种格式&#xff0c;边际图有11种格式&#xff0c;共计88种组合&#xff0c;另外模板中给了8款配色&#xff0c;我愿称其为888组合&#xff0c;只需要更换一下数据就能绘制出各种类型的边际图: 甚至…

中国机器视觉市场研究报告

目录 机器视觉行业概述机器视觉行业发展现状机器视觉行业典型企业分析机器视觉行业未来发展趋势 机器视觉行业概述 机器视觉定义 机器视觉&#xff08;Machine Vision&#xff0c;MV&#xff09;是人工智能正在快速发展的一个分支。根据美国制造工程师协会&#xff08;SME&…

数字孪生虚拟电厂负荷控制系统可视化

随着国家“双碳”及“构建以新能源为主体的新型电力系统”等目标的提出&#xff0c;清洁化、数字化越来越成为电力系统面临的迫切需求&#xff0c;负控系统的发展对电力营销现代化建设具有重要的意义。负控管理系统是一个着眼于全面加强电力信息管理的&#xff0c;集负荷控制、…

Tips for Confluence Administrators: Part 2

Part 1中&#xff0c;我们谈到了 Confluence 自定义配置的案例&#xff0c;例如&#xff1a;如何禁用附件下载&#xff1f;如何将iFrame放入Confluence&#xff1f;如何使我的页面完全私有&#xff1f;如何防止空间管理员删除他们的空间&#xff1f;任何软件都有bug&#xff0c…

Minecraft 1.19.2 Forge模组开发 11.Mixin

我们本次使用Mixin在1.19.2中制作一个属于自己的不死图腾。 演示效果演示效果演示效果 什么是Mixin&#xff1f; 简单来说是通过注入一些我们的代码&#xff0c;达到对MC原版内容的修改。 详细内容可以参考Minecraft 17.1 Mixin 1.首先我们需要在开发包中引入mixin的依赖&a…

深度学习——双向循环神经网络(笔记)

双向循环神经网络&#xff1a; ①对于序列来讲&#xff0c;假设的目标是&#xff1a;给定观测的情况下&#xff08;在时间序列的上下文或语言模型的上下文&#xff09;&#xff0c;对于下一个输出进行建模 ②对于序列模型来讲&#xff0c;可以从前往后看&#xff0c;也可以从…

Servlet基础

Servlet1. Servlet概述2. 快速入门3. 执行原理4. 生命周期方法5. Servlet3.06. 体系结构7. 相关配置8. HTTP8.1 概念8.2 Request8.3 Response8.4 ServletContext综合案例:文件下载&#xff1a;1. Servlet概述 Servlet是JavaEE规范(接口)之一Servlet是JavaWeb三大组件之一&…

使用sdk-npi-enablement-tool生成SVD文件和芯片头文件

使用sdk-npi-enablement-tool生成SVD文件和芯片头文件 文章目录使用sdk-npi-enablement-tool生成SVD文件和芯片头文件IntroductionOverviewOperation Steps创建芯片配置文件yaml填充外设模块的寄存器映射描述文件xlsx验证生成芯片头文件ConclusionIntroduction 芯片验证与测试…

【Linux杂篇】Linux系统终端常用配置文件更改

目录列表&#xff1a; 1.alias别名永久保存 2.解决vim文件没有颜色的问题 3.vim插件supertap插件安装&#xff08;可支持自动补全&#xff0c;非函数代码补全&#xff0c;仅支持在当前编辑文档内补全&#xff09; 4.vim插件管理 5.YCM下载 6.解决vim中使用backspace无法删…

windows安装npm和cnpm

npm: 代码的包管理器&#xff0c;但是服服器在国外&#xff0c;每一次启动项目都要下载一些依赖&#xff0c;耗时之久&#xff0c;官网下载链接戳 npm。 cnpm&#xff1a;这是淘宝团队出的npm的镜像&#xff0c;可用此代替官方的只读版本&#xff0c;官网链接 cnpm。 先安装np…

Redis6学习笔记【part3】配置文件与订阅/发布

一.Redis配置文件 1.Units单位 配置大小单位,开头定义了一些基本的度量单位&#xff0c;只支持bytes&#xff0c;不支持bit。其中 GB、Gb 大小写不敏感。 2.Include包含 类似 jsp 中的 include 引入公共页面 &#xff0c;redis 在多实例的情况也可以把公用的配置文件提取出来…

9 大指标分析 Solana 的熊市危机

Daniel, 2023 年 1 月Solana 是一个去中心化的区块链网络&#xff0c;由 Solana 实验室设计并在2020年推出&#xff0c;具有快速、可扩展和安全的特点。由于其快速的交易速度和低交易费用&#xff0c;Solana 在 2020 年和 2021 年获得了极大的关注&#xff0c;这使得它对去中心…

远程仓库操作

添加远程仓库 新建一个文件夹&#xff1a; 文件夹右键打开git bash: 初始化为git仓库&#xff1a; 在码云上新建一个git仓库&#xff1a; 复制链接&#xff1a; 在文件夹里使用git bash&#xff1a; git remote add<shortname><url> 添加一个新的远程仓库&…

制作tomcat的docker镜像

环境信息&#xff1a;MacBook Pro&#xff08;M1&#xff09;VMware-fusion(Player 版本 13.0.0 (20802013))Ubuntu 22.10tomcat镜像&#xff1a;centos-7.9.2009jdk1.8.0_341 apache-tomcat-8.5.84制作步骤&#xff1a;&#xff08;1&#xff09;下载好tomcat/jdk(我是在macbo…