MyBaties实现批量插入

  • 一、SQL实现示例
  • 二、Mybaties通过Mapper.xml文件实现
  • 三、在Mapper接口上使用注解
  • 四、限制一次批量插入数据的数量

一、SQL实现示例

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

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

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

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

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

二、Mybaties通过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()->组成一个toListList<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();}}
}

MyBaties实现批量插入相关推荐

  1. mapper批量插入

    1.常规方式的批量插入 sql语句 int bathNorm(List<Teacher> teacherList);<insert id="bathNorm" p ...

  2. ssm 批量插入案例(MySQL)

    用ssm框架批量插入记录的简单案例,批量插入用的不是很多,但是用的过程中问题较多 数据库为mysql,数据库设计为主键自增长, 很少写博客,有不足之处还请留言,绝对对你有帮助,请给个赞吧! POLO中 ...

  3. node mysql 批量写入_请问如何使用node.js在MySQL中进行批量插入

    catspeake 我四处寻找关于批量插入对象的答案.Ragnar123的回答使我得出了这样的结论:function bulkInsert(connection, table, objectArray ...

  4. MySQL 批量插入:如何不插入重复数据?

    以下文章来源方志朋的博客,回复"666"获面试宝典 知识这个东西,看来真的要温故而知新,一直不用,都要忘记了???? 业务很简单:需要批量插入一些数据,数据来源可能是其他数据库的表 ...

  5. 批量插入数据库语句java_java相关:MyBatis批量插入数据到Oracle数据库中的两种方式(实例代码)...

    java相关:MyBatis批量插入数据到Oracle数据库中的两种方式(实例代码) 发布于 2020-7-22| 复制链接 本文通过实例代码给大家分享了MyBatis批量插入数据到Oracle数据库 ...

  6. mysql注解批量添加mybatis_Mybatis通过注解方式实现批量插入数据库 及 常见的坑

    MyBatis中通过xml文件配置数据库批量操作的文章很多,比如这篇http://www.cnblogs.com/xcch/articles/2042298.html,但探讨如何通过注解配置实现同样效 ...

  7. Java豆瓣电影爬虫——减少与数据库交互实现批量插入

    节前一个误操作把mysql中record表和movie表都清空了,显然我是没有做什么mysql备份的.所以,索性我把所有的表数据都清空的,一夜回到解放前-- 项目地址:https://github.c ...

  8. oracle insert汉字出错,Oracle数据库之Oracle批量插入数据SQL语句太长出错:无效的主机/绑定变量名...

    本文主要向大家介绍了Oracle数据库之Oracle批量插入数据SQL语句太长出错:无效的主机/绑定变量名,通过具体的内容向大家展现,希望对大家学习Oracle数据库有所帮助. Oracle数据库,用 ...

  9. 批量插入/修改网页代码的asp脚本

    这东西最初目的是为了给虚拟主机上数百个站同时插入***代码来用的!(指有跨站权限的虚拟主机) 当然,也可以用来批量插入/修改网页文件,稍加修改即可! 代码如下,很简单!复制下来存成.asp文件,放到网 ...

最新文章

  1. 打造一流创新环境:协作、开放、可持续
  2. maven学习笔记之IDEA+Maven+Jetty运行一个简单的web项目
  3. 复现经典:《统计学习方法》​第17章 潜在语义分析
  4. Python代码列主元消去法matlab编程_工业机器人用什么语言编程的?
  5. linux中使用xshell远程连接
  6. 天池在线编程 2020年9月26日 日常周赛题解
  7. 所有可能出栈序列总数
  8. 关于LUA+Unity开发_XLua篇
  9. 安卓应用安全指南 5.6.1 密码学 示例代码
  10. Neutron系列 : Neutron OVS OpenFlow 流表 和 L2 Population(8)
  11. Firefox的缓存问题
  12. adb 黑域app_黑域app|黑域手机工具下载 V1.3_下载 - 偶要下载手机频道
  13. soundpool android,android – 如何获取Soundpool的持续时间
  14. 登录不了WPS国际版,密码正确,在网页能够正常登录,在WPS不行,求解答,版本号是10.2.0.7646已刷语言包
  15. PLC同时连接多个触摸屏和电视机显示器解决方案
  16. 贵州:科技创新促高质量发展
  17. 子标签获取父级Id值
  18. 同时使用网线以及无线上网
  19. 理财产品信息管理系统项目代码分享
  20. runauto.. 病毒斗争记

热门文章

  1. virbr0怎么关闭_centos7关闭virbr0虚拟网卡
  2. windres.exe执行错误提示‘gcc‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。解决方法
  3. 聊聊旷厂黑科技 | 为了让手机拍出好照片,我们开发了100多种算法
  4. 用JS画斐波那契螺旋线(黄金螺旋线)
  5. android TextView 设置省略号结尾
  6. MongoDB面试题(史上最全面试题,精心整理100家互联网企业,面试必过)
  7. Python 窗体美化,背景图片,字体样式
  8. 管螺纹如何标注_老师!请问这种螺纹孔怎么标注啊??机械设计教程螺纹知识教学!...
  9. css-怎么做半圆渐变背景图
  10. kafka详解三:开发Kafka应用