Mybatis如何执行批量操作

文章目录

    • Mybatis如何执行批量操作
      • 使用foreach标签
    • 使用ExecutorType.BATCH
      • 如何获取生成的主键

Mybatis如何执行批量操作

使用foreach标签

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach标签的属性主要有item,index,collection,open,separator,close。
item  表示集合中每一个元素进行迭代时的别名,随便起的变量名;
index  指定一个名字,用于表示在迭代过程中,每次迭代到的位置,不常用;
open  表示该语句以什么开始,常用“(”;
separator表示在每次进行迭代之间以什么符号作为分隔符,常用“,”;
close 表示以什么结束,常用“)”。
在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:

  • 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
  • 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
  • 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
    具体用法如下:
<!-- 批量保存(foreach插入多条数据两种方法)
       int addEmpsBatch(@Param("emps") List<Employee> emps); -->
<!-- MySQL下批量保存,可以foreach遍历 mysql支持values(),(),()语法 --> //推荐使用
<insert id="addEmpsBatch">
    INSERT INTO emp(ename,gender,email,did)
    VALUES
    <foreach collection="emps" item="emp" separator=",">
        (#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
    </foreach>
</insert>

<!-- 这种方式需要数据库连接属性allowMutiQueries=true的支持
 如jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true -->  
<insert id="addEmpsBatch">
    <foreach collection="emps" item="emp" separator=";">                                 
        INSERT INTO emp(ename,gender,email,did)
        VALUES(#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
    </foreach>
</insert>

使用ExecutorType.BATCH

Mybatis内置的ExecutorType有3种,默认为simple,该模式下它为每个语句的执行创建一个新的预处理语句,单条提交sql;而batch模式重复使用已经预处理的语句,并且批量执行所有更新语句,显然batch性能将更优; 但batch模式也有自己的问题,比如在Insert操作时,在事务没有提交之前,是没有办法获取到自增的id,这在某型情形下是不符合业务要求的

具体用法如下

//批量保存方法测试
@Test  
public void testBatch() throws IOException{
    SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    //可以执行批量操作的sqlSession
    SqlSession openSession = sqlSessionFactory.openSession(ExecutorType.BATCH);

    //批量保存执行前时间
    long start = System.currentTimeMillis();
    try {
        EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
        for (int i = 0; i < 1000; i++) {
            mapper.addEmp(new Employee(UUID.randomUUID().toString().substring(0, 5), "b", "1"));
        }
        openSession.commit();
        long end = System.currentTimeMillis();
        //批量保存执行后的时间
        System.out.println("执行时长" + (end - start));
        //批量 预编译sql一次==》设置参数==》10000次==》执行1次   677
        //非批量  (预编译=设置参数=执行 )==》10000次   1121
    } finally {
        openSession.close();
    }
}

mapper和mapper.xml如下

public interface EmployeeMapper {   
    //批量保存员工
    Long addEmp(Employee employee);
}
<mapper namespace="com.jourwon.mapper.EmployeeMapper"
     <!--批量保存员工 -->
    <insert id="addEmp">
        insert into employee(lastName,email,gender)
        values(#{lastName},#{email},#{gender})
    </insert>
</mapper>

如何获取生成的主键

对于支持主键自增的数据库(MySQL)

<insert id="insertUser" useGeneratedKeys="true" keyProperty="userId" >
    insert into user( 
    user_name, user_password, create_time) 
    values(#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP})
</insert>

parameterType 可以不写,Mybatis可以推断出传入的数据类型。如果想要访问主键,那么应当parameterType 应当是java实体或者Map。这样数据在插入之后 可以通过ava实体或者Map 来获取主键值。通过 getUserId获取主键

不支持主键自增的数据库(Oracle)

对于像Oracle这样的数据,没有提供主键自增的功能,而是使用序列的方式获取自增主键。
可以使用<selectKey>标签来获取主键的值,这种方式不仅适用于不提供主键自增功能的数据库,也适用于提供主键自增功能的数据库
<selectKey>一般的用法

<selectKey keyColumn="id" resultType="long" keyProperty="id" order="BEFORE">
</selectKey> 

在这里插入图片描述

<insert id="insertUser" >
	<selectKey keyColumn="id" resultType="long" keyProperty="userId" order="BEFORE">
		SELECT USER_ID.nextval as id from dual 
	</selectKey> 
	insert into user( 
	user_id,user_name, user_password, create_time) 
	values(#{userId},#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP})
</insert>

此时会将Oracle生成的主键值赋予userId变量。这个userId 就是USER对象的属性,这样就可以将生成的主键值返回了。如果仅仅是在insert语句中使用但是不返回,此时keyProperty=“任意自定义变量名”,resultType 可以不写。
Oracle 数据库中的值要设置为 BEFORE ,这是因为 Oracle中需要先从序列获取值,然后将值作为主键插入到数据库中。

扩展
如果Mysql 使用selectKey的方式获取主键,需要注意下面两点:

order : AFTER
获取递增主键值 :SELECT LAST_INSERT_ID()

当实体类中的属性名和表中的字段名不一样 ,怎么办
第1种: 通过在查询的SQL语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。

<select id="getOrder" parameterType="int" resultType="com.jourwon.pojo.Order">
       select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};
</select>

第2种: 通过<resultMap>来映射字段名和实体类属性名的一一对应的关系。

<select id="getOrder" parameterType="int" resultMap="orderResultMap">
	select * from orders where order_id=#{id}
</select>

<resultMap type="com.jourwon.pojo.Order" id="orderResultMap">
    <!–用id属性来映射主键字段–>
    <id property="id" column="order_id">

    <!–用result属性来映射非主键字段,property为实体类属性名,column为数据库表中的属性–>
    <result property ="orderno" column ="order_no"/>
    <result property="price" column="order_price" />
</reslutMap>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL系统函数

select version();查看mysql版本。 select user();可以查看数据库用户名。 select database();可以查看数据库名。 select system_use();可以查看系统用户名。 show variables like %basedir%;可以展示数据库读取路径。 show variables like %sets_dir%;可以看一下安…

★136. 只出现一次的数字(位运算)

136. 只出现一次的数字 这个题主要考察的知识点是位运算&#xff08;这里是异或&#xff09; 如果不要求空间复杂度为O&#xff08;1&#xff09;&#xff0c;那有很多方法。但是这里有这样的要求。 可以通过位运算 的方法来实现。 异或运算 ⊕有以下三个性质&#xff1a; 任…

文字转语音、语音转文字! AI视频生成神器!

分享一波文字转语音、语音转文字&#xff01;AI视频生成神器&#xff01;让外国人说中文&#xff0c;口型自然&#xff0c;不限语言&#xff0c;感兴趣的同学可以试试~ 可以用Al生成视频&#xff0c;Whisper语音转文字 Whisper 开源项目&#xff1a; https://github.com/Const…

【源码解析】聊聊线程池 实现原理与源码深度解析(二)

AbstractExecutorService 上一篇文章中&#xff0c;主要介绍了AbstractExecutorService的线程执行的核心流程&#xff0c;execute() 这个方法显然是没有返回执行任务的结果&#xff0c;如果我们需要获取任务执行的结果&#xff0c;怎么办&#xff1f; Callable 就是一个可以获…

(C语言)通过循环按行顺序为一个矩阵赋予1,3,5,7,9,等奇数,然后输出矩阵左下角的值。

#include<stdio.h> int main() {int a[5][5];int n 1;for(int i 0;i < 5;i ){for(int j 0;j < 5;j ){a[i][j] n;n 2;}}for(int i 0;i < 5;i ){for(int j 0;j < i;j )printf("%-5d",a[i][j]);printf("\n");}return 0; } 运行截图…

电子学会C/C++编程等级考试2022年06月(四级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:公共子序列 我们称序列Z = < z1, z2, ..., zk >是序列X = < x1, x2, ..., xm >的子序列当且仅当存在 严格上升 的序列< i1, i2, ..., ik >,使得对j = 1, 2, ... ,k, 有xij = zj。比如Z = < a, b, f, c &…

【信息安全】MD5哈希函数

1. MD5介绍 MD5&#xff08;Message Digest Algorithm 5&#xff09;是一种常见的哈希函数&#xff0c;通常用于产生数据的数字摘要&#xff0c;也称为哈希值或摘要值。它是由Ron Rivest在1991年设计的&#xff0c;广泛用于数据完整性验证、密码存储、数字签名等领域。 MD5哈…

游戏被流量攻击会有什么样的影响,该用什么样的防护方式去处理

德迅云安全-领先云安全服务与解决方案提供商德迅云游戏盾专门针对游戏进行防护&#xff0c;可免费提供防护方案~ 如果游戏被流量攻击会产生以下影响&#xff1a; 服务器过载&#xff1a;流量攻击会导致游戏服务器接收到的请求数量急剧增加&#xff0c;超出服务器的处理能力。这…

新媒体营销教学模拟实训平台解决方案

一、背景与目标 随着新媒体的快速发展&#xff0c;营销人才需求旺盛&#xff0c;而具备新媒体营销能力的人才供给却相对不足。为了解决这一矛盾&#xff0c;本方案旨在构建一个新媒体营销教学模拟实训平台&#xff0c;帮助学生掌握新媒体营销的实际操作技能&#xff0c;提高就…

xcode swiftui项目添加依赖

打开项目targets——Build Phases 点击“” 属于Apple SDKs的依赖可以直接添加 其他依赖需要在 Add Other中添加&#xff0c;在右上角用名字搜索或者URL地址(如GitHub上插件的地址)搜索,然后添加&#xff0c;也可添加本地文件

Linux Camera Driver(2):CIS设备注册(DTS)

一:MIPI接口 1、硬件接口 MIPI接口以rv1109和gc2053的硬件为例进行说明: 2、ISP驱动 注意配置事项: endpoint配置,必须指定data-lanes,否则无法识别为mipi类型 链接方式:sensor->csi_dphy->isp->ispp (1)sensor节点配置 根据原理图可知:mipicsi_clk0即引…

推荐一本Python数据分析的书:《Python数据科学应用从入门到精通》(张甜 杨维忠 著 2023年11月新书 清华大学出版社)

1.Python是堪与Office办公软件比肩的职场人士必备技能 Python作为一门简单、易学、易读、易维护、用途广泛、速度快、免费、开源的主流编程语言&#xff0c;广泛应用于Web开发、大数据处理、人工智能、云计算、爬虫、游戏开发、自动化运维开发等各个领域&#xff0c;是众多高等…

抖音视频水印怎么去除?这三个视频去水印技巧值得收藏!

抖音视频水印怎么去除&#xff1f;随着互联网的持续发展&#xff0c;越来越多的人选择使用视频分享平台来展示他们的生活与工作。然而&#xff0c;上传到这些平台上的许多视频常常遭到恶意水印的攻击&#xff0c;严重影响了观众的观看体验。今天&#xff0c;我们将分享三个视频…

网盘系统设计:万亿 GB 网盘如何实现秒传与限速?

Java全能学习面试指南&#xff1a;https://javaxiaobear.cn 网盘&#xff0c;又称云盘&#xff0c;是提供文件托管和文件上传、下载服务的网站&#xff08;File hostingservice&#xff09;。人们通过网盘保管自己拍摄的照片、视频&#xff0c;通过网盘和他人共享文件&#xff…

跨域问题与解决-gatway

3.6.1.什么是跨域问题 跨域&#xff1a;域名不一致就是跨域&#xff0c;主要包括&#xff1a; 域名不同&#xff1a; www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com域名相同&#xff0c;端口不同&#xff1a;localhost:8080和localhost8081 跨域问题&a…

回溯法及例题(C++实现)

回溯法概念 概念&#xff1a;在包含问题所有解的解空间树中&#xff0c;按照深度优先搜索的策略&#xff0c;根据根结点&#xff08;开始节点&#xff09;出发搜索解空间树。 流程&#xff1a;首先根结点成为活节点&#xff0c;同时也成为当前的扩展结点。在当前的扩展结点处…

智能优化算法(二):禁忌搜索算法

文章目录 禁忌搜索算法1.禁忌搜索算法预备知识1.1 预备知识1---解空间1.2.预备知识2---邻域 2.禁忌搜索算法实现过程2.1.禁忌搜索算法思想2.2.禁忌搜索构成要素2.2.1.搜索结果表达2.2.2.邻域移动策略2.2.3.禁忌表引入2.2.4.禁忌搜索选择策略2.2.5.禁忌搜索渴望水平2.2.6.禁忌搜…

[Mac软件]HitPaw Video Converter 功能强大的视频格式转换编辑软件激活版

软件介绍&#xff1a; 以令人难以置信的速度将无损视频和音乐转换为1000多种格式&#xff1a;MP4、MOV、AVI、VOB、MKV等。不仅适用于普通编解码器&#xff0c;也适用于高级VP9、ProRes和Opus编码器。这解决了您不支持格式的所有问题&#xff0c;并允许您在任何平台和设备上播…

美颜SDK是什么?集成第三方美颜SDK的步骤

第三方美颜SDK提供了实时美颜效果。本文将深入探讨集成第三方美颜SDK的步骤&#xff0c;助您在应用中实现引人注目的美颜功能。 第一步&#xff1a;选择适合的第三方美颜SDK 在开始之前&#xff0c;务必仔细选择一个适合您应用需求的第三方美颜SDK。不同的SDK可能具有不同的特…

顺序查找、折半查找、分块查找

概念 查找表&#xff0c;分为静态查找表和动态查找表。 顺序查找 效率分析&#xff1a; 优化 折半查找 折半查找&#xff0c;又称“二分查找”仅适用于有序的顺序表。 ⭐&#xff0c;因为顺序表可以随机访问&#xff0c;链表不可以 效率分析 折半查找判定树的构造 如果&…