我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MyBatis实现批量插入方法实例

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MyBatis实现批量插入方法实例

一、SQL实现示例

假设我们只插入一条数据的时候,SQL如下

insert into table ([列名],[列名])  values ([列值],[列值]));
# 或者
insert into table values ([列值],[列值]))

当插入多条数据的时候,也就是需要批量插入的时候,SQL如下

insert into table ([列名],[列名])
VALUES
([列值],[列值])),
([列值],[列值])),
([列值],[列值]));

批量的用处:一次插入多条数据,这样就可以降低与数据库的IO次数,减少性能的损耗。

二、Mybatis通过Mapper.xml文件实现

比如这里的抽象的SQL就是

 insert into table (ID, PHONE,MESSAGE,APP_CODE,AREA_CODE,SEND_TYPE,SEND_TIME,CREATE_DATE,REMARK,serial_number)
 values
 (?,?,?,?,?,?,?,?,?,?,?,), (?,?,?,?,?,?,?,?,?,?,?,), (?,?,?,?,?,?,?,?,?,?,?,)

具体实现

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.scoreone.ap.mapper.MtTaskMapper">
<!--批量插入-->
	<insert id="insertList" parameterType="java.util.List">
		insert into ap_mt_task (ID, PHONE, MESSAGE,
		APP_CODE, AREA_CODE, SEND_TYPE,
		SEND_TIME, CREATE_DATE, REMARK,serial_number
		)
		VALUES
		<foreach collection="list" index="index" item="item" separator="," >
			(#{item.ID},#{item.PHONE},#{item.MESSAGE},#{item.APP_CODE},#{item.AREA_CODE},
			#{item.SEND_TYPE},#{item.SEND_TIME},#{item.CREATE_DATE},#{item.REMARK},#{item.serial_number})
		</foreach>
	</insert>
</mapper>

也可以不用在value里用foreach ,在整个SQL语句外面用。

参数解释

foreach的主要作用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有 collection,item,separator,index,open,close。

collection:指定要遍历的集合。表示传入过来的参数的数据类型。该属性是必须指定的,要做 foreach 的对象。在使用foreach的时候最关键的也是最容易出错的就是collection属性。在不同情况 下,该属性的值是不一样的,主要有一下3种情况:

  • a. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
  • b. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
  • c. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map。Map 对象没有默认的键

item:表示集合中每一个元素进行迭代时的别名。将当前遍历出的元素赋值给指定的变量,然后用#{变量名},就能取出变量的值,也就是当前遍历出的元素。

separator:表示在每次进行迭代之间以什么符号作为分隔符。select * from tab where id in(1,2,3)相当于1,2,3之间的","

index:索引。index指定一个名字,用于表示在迭代过程中,每次迭代到的位置。遍历list的时候index就是索引,遍历map的时候index表示的就是map的key,item就是map的值。

open:表示该语句以什么开始,close表示以什么结束。

三、在Mapper接口上使用注解

举例

@Insert(“insert into blog(blogId,title,author) values(#blogId,#title,#author)”)
public boolean saveBlog(Blog blog);

这种对于简单的SQL可以使用法,对于复杂的SQL可读性太差(会有以大堆拼接符号),不建议使用。

xml、注解两种方式的区别:

foreach相当语句逐条INSERT语句执行,将出现如下问题:

(1)mapper接口的insert方法返回值将是最后一条INSERT语句的操作成功的记录数目(就是0或1),而不是所有INSERT语句的操作成功的总记录数目;

(2)当其中一条不成功时,不会进行整体回滚。

注解方式:当有一条插入不成功时,会整体回滚。

四、限制一次批量插入数据的数量

假设我们传过来的List一次有 10000 条,但是我们数据库批量插入不可能一下子插入 10000 条,我们就需要将这一批的数据进行限制,也就是再分成一小批一小批进行插入,比如下面,一次限制插入 15 条数据。

//举例这里就是进行 task表 的批量插入,限制一次 15 条
public int insertList(ArrayList<MtTask> taskList) {
//批量插入的时候,限制一批插入 15 条,效率会高一点,防止造成堆内存溢出异常
        if (taskList.size() > 0) {
            int InsertSize = 15;//一次插入15条
            //分成limit次发请求到数据库
            //这个算法就是防止不是在整除的时候少了一次,比如 32 个需要插四次
            int limit = (taskList.size() + InsertSize - 1) / InsertSize;//需要插入多少次

            //这个流的意思就是,进行 limit 次,每一次插入15个

            //根据起始值seed(0),每次生成一个指定递增值(n+1)的数,limit(limit)用于截断流的长度,也就是进行limit次的里面的操作
            Stream.iterate(0, n -> n + 1).limit(limit).forEach(a -> {
                // skip就是跳过前面(a * InsertSize)条数据,因为 a是从0开始,到limit,skip(0)的时候是空的不插入
                // .limit(InsertSize)->限制每次插入数据的15条  .collect(Collectors.toList()->组成一个toList
                List<MtTask> mtTaskList = taskList.stream().skip(a * InsertSize).limit(InsertSize).collect(Collectors.toList());
                //doSomething();
                mtTaskMapper.insertList(mtTaskList);
            });
}

上面这是使用流的,下面是不用使用流的


            //集合的大小
            int size = taskList.size();
            //需要拆分成的每个集合大小
            int newSize = 15;
            //需要需要拆分成的小集合数量(拆分没有余数则取相除的结果,如果有余数则需要再加一个集合存放余数)
            //这个就是直接判断出了之后有没有余数,有就多加一次,没有就整除刚好
            int sum = size % newSize != 0 ? (size / newSize) + 1 : size / newSize;
            //循环参照大集合,能拆分成的集合有多少个就循环多少遍
            for (int i = 0; i < sum; i++) {
                //如果当前下标+1 等于拆分成的集合数量,则说明这是最后一组(也可能仅能拆成一个集合 下标0 + 1 == 集合数量 1)
                if ((i + 1) == sum) {
                    //截取的下标开始位
                    int startIndex = (i * newSize);
                    //截取的结束下标位置
                    int endIndex = size;
                    //插入
                    result = mtTaskMapper.insertList(taskList.subList(startIndex, endIndex));
                } else {
                    //截取的下标开始位
                    int startIndex = (i * newSize);
                    //截取的结束下标位置
                    int endIndex = (i + 1) * newSize;
                    result = mtTaskMapper.insertList(taskList.subList(startIndex, endIndex));
                }
            }

=还有一种就是达到我们限制的数量就插入

@Override
public int insertList(ArrayList<MtTask> taskList) {

if(!CollectionUtils.isEmpty(taskList)){
            List<MtTask> subList = new ArrayList<>();
            int num = 0;
            for (MtTask mtTask : taskList ){
                subList.add(mtTask);
                num ++ ;
                if(num >= 500){
                    mtTaskMapper.insertList(subList);
                    subList.clear();
                    subList = new ArrayList<>();
                }
            }
            if(num > 0){
                mtTaskMapper.insertList(subList);
                subList.clear();
            }
        }
}

总结

到此这篇关于MyBatis实现批量插入的文章就介绍到这了,更多相关MyBatis批量插入内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

MyBatis实现批量插入方法实例

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

MyBatis实现批量插入方法实例

最近在公司项目开发中遇到批量数据插入或者更新,下面这篇文章主要给大家介绍了关于MyBatis实现批量插入的相关资料,需要的朋友可以参考下
2022-11-13

MyBatis iterate实现批量插入优化

MyBatis 的 iterate 方法允许你执行批量插入操作,但是默认情况下,这种操作可能会受到数据库的限制。为了优化批量插入操作,你可以采取以下措施:使用 JDBC 批处理(Batch Processing):在 MyBatis 中,
MyBatis iterate实现批量插入优化
2024-09-19

MyBatis如何实现批量插入数据

本文小编为大家详细介绍“MyBatis如何实现批量插入数据”,内容详细,步骤清晰,细节处理妥当,希望这篇“MyBatis如何实现批量插入数据”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、SQL实现示例假设我们
2023-07-04

MyBatis批量查询、插入、更新、删除的实现示例

由于需要处理短时间内大量数据入库的问题,想到了Mybatis的批量操作,本文主要介绍了MyBatis批量查询、插入、更新、删除的实现示例,感兴趣的可以了解一下
2023-05-20

Mybatis-Plus通过SQL注入器实现批量插入的实践

本文主要介绍了Mybatis-Plus通过SQL注入器实现批量插入的实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2022-11-13

mybatis怎么实现批量插入并返回主键

本篇内容主要讲解“mybatis怎么实现批量插入并返回主键”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mybatis怎么实现批量插入并返回主键”吧!mybatis批量插入并返回主键(xml和注
2023-06-21

MyBatis批量查询、插入、更新、删除如何实现

今天小编给大家分享的是MyBatis批量查询、插入、更新、删除如何实现,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。1.批量查询提供两种方式。方式一,返回值: List
2023-07-06

Mybatis-Plus批量插入用法详解

mybatis-plus的IService接口默认提供saveBatch批量插入,也是唯一一个默认批量插入,在数据量不是很大的情况下可以直接使用,但这种是一条一条执行的效率上会有一定的瓶颈,今天我们就来研究研究mybatis-plus中的批量插入
2023-02-15

如何使用Mybatis的Batch Insert Support实现批量插入

这篇文章主要介绍了如何使用Mybatis的Batch Insert Support实现批量插入的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何使用Mybatis的Batch Insert Support实现批
2023-07-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录