最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis實(shí)現(xiàn)批量插入方法實(shí)例

 更新時(shí)間:2022年10月26日 16:17:27   作者:小怪吖  
最近在公司項(xiàng)目開(kāi)發(fā)中遇到批量數(shù)據(jù)插入或者更新,下面這篇文章主要給大家介紹了關(guān)于MyBatis實(shí)現(xiàn)批量插入的相關(guān)資料,需要的朋友可以參考下

一、SQL實(shí)現(xiàn)示例

假設(shè)我們只插入一條數(shù)據(jù)的時(shí)候,SQL如下

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

當(dāng)插入多條數(shù)據(jù)的時(shí)候,也就是需要批量插入的時(shí)候,SQL如下

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

批量的用處:一次插入多條數(shù)據(jù),這樣就可以降低與數(shù)據(jù)庫(kù)的IO次數(shù),減少性能的損耗。

二、Mybatis通過(guò)Mapper.xml文件實(shí)現(xiàn)

比如這里的抽象的SQL就是

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

具體實(shí)現(xiàn)

<?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 ,在整個(gè)SQL語(yǔ)句外面用。

參數(shù)解釋

foreach的主要作用在構(gòu)建in條件中,它可以在SQL語(yǔ)句中進(jìn)行迭代一個(gè)集合。foreach元素的屬性主要有 collection,item,separator,index,open,close。

collection:指定要遍歷的集合。表示傳入過(guò)來(lái)的參數(shù)的數(shù)據(jù)類型。該屬性是必須指定的,要做 foreach 的對(duì)象。在使用foreach的時(shí)候最關(guān)鍵的也是最容易出錯(cuò)的就是collection屬性。在不同情況 下,該屬性的值是不一樣的,主要有一下3種情況:

  • a. 如果傳入的是單參數(shù)且參數(shù)類型是一個(gè)List的時(shí)候,collection屬性值為list
  • b. 如果傳入的是單參數(shù)且參數(shù)類型是一個(gè)array數(shù)組的時(shí)候,collection的屬性值為array
  • c. 如果傳入的參數(shù)是多個(gè)的時(shí)候,我們就需要把它們封裝成一個(gè)Map了,當(dāng)然單參數(shù)也可以封裝成map。Map 對(duì)象沒(méi)有默認(rèn)的鍵

item:表示集合中每一個(gè)元素進(jìn)行迭代時(shí)的別名。將當(dāng)前遍歷出的元素賦值給指定的變量,然后用#{變量名},就能取出變量的值,也就是當(dāng)前遍歷出的元素。

separator:表示在每次進(jìn)行迭代之間以什么符號(hào)作為分隔符。select * from tab where id in(1,2,3)相當(dāng)于1,2,3之間的","

index:索引。index指定一個(gè)名字,用于表示在迭代過(guò)程中,每次迭代到的位置。遍歷list的時(shí)候index就是索引,遍歷map的時(shí)候index表示的就是map的key,item就是map的值。

open:表示該語(yǔ)句以什么開(kāi)始,close表示以什么結(jié)束。

三、在Mapper接口上使用注解

舉例

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

這種對(duì)于簡(jiǎn)單的SQL可以使用法,對(duì)于復(fù)雜的SQL可讀性太差(會(huì)有以大堆拼接符號(hào)),不建議使用。

xml、注解兩種方式的區(qū)別:

foreach相當(dāng)語(yǔ)句逐條INSERT語(yǔ)句執(zhí)行,將出現(xiàn)如下問(wèn)題:

(1)mapper接口的insert方法返回值將是最后一條INSERT語(yǔ)句的操作成功的記錄數(shù)目(就是0或1),而不是所有INSERT語(yǔ)句的操作成功的總記錄數(shù)目;

(2)當(dāng)其中一條不成功時(shí),不會(huì)進(jìn)行整體回滾。

注解方式:當(dāng)有一條插入不成功時(shí),會(huì)整體回滾。

四、限制一次批量插入數(shù)據(jù)的數(shù)量

假設(shè)我們傳過(guò)來(lái)的List一次有 10000 條,但是我們數(shù)據(jù)庫(kù)批量插入不可能一下子插入 10000 條,我們就需要將這一批的數(shù)據(jù)進(jìn)行限制,也就是再分成一小批一小批進(jìn)行插入,比如下面,一次限制插入 15 條數(shù)據(jù)。

//舉例這里就是進(jìn)行 task表 的批量插入,限制一次 15 條
public int insertList(ArrayList<MtTask> taskList) {
//批量插入的時(shí)候,限制一批插入 15 條,效率會(huì)高一點(diǎn),防止造成堆內(nèi)存溢出異常
        if (taskList.size() > 0) {
            int InsertSize = 15;//一次插入15條
            //分成limit次發(fā)請(qǐng)求到數(shù)據(jù)庫(kù)
            //這個(gè)算法就是防止不是在整除的時(shí)候少了一次,比如 32 個(gè)需要插四次
            int limit = (taskList.size() + InsertSize - 1) / InsertSize;//需要插入多少次

            //這個(gè)流的意思就是,進(jìn)行 limit 次,每一次插入15個(gè)

            //根據(jù)起始值seed(0),每次生成一個(gè)指定遞增值(n+1)的數(shù),limit(limit)用于截?cái)嗔鞯拈L(zhǎng)度,也就是進(jìn)行l(wèi)imit次的里面的操作
            Stream.iterate(0, n -> n + 1).limit(limit).forEach(a -> {
                // skip就是跳過(guò)前面(a * InsertSize)條數(shù)據(jù),因?yàn)?a是從0開(kāi)始,到limit,skip(0)的時(shí)候是空的不插入
                // .limit(InsertSize)->限制每次插入數(shù)據(jù)的15條  .collect(Collectors.toList()->組成一個(gè)toList
                List<MtTask> mtTaskList = taskList.stream().skip(a * InsertSize).limit(InsertSize).collect(Collectors.toList());
                //doSomething();
                mtTaskMapper.insertList(mtTaskList);
            });
}

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

/*不用流的方法*/
            //集合的大小
            int size = taskList.size();
            //需要拆分成的每個(gè)集合大小
            int newSize = 15;
            //需要需要拆分成的小集合數(shù)量(拆分沒(méi)有余數(shù)則取相除的結(jié)果,如果有余數(shù)則需要再加一個(gè)集合存放余數(shù))
            //這個(gè)就是直接判斷出了之后有沒(méi)有余數(shù),有就多加一次,沒(méi)有就整除剛好
            int sum = size % newSize != 0 ? (size / newSize) + 1 : size / newSize;
            //循環(huán)參照大集合,能拆分成的集合有多少個(gè)就循環(huán)多少遍
            for (int i = 0; i < sum; i++) {
                //如果當(dāng)前下標(biāo)+1 等于拆分成的集合數(shù)量,則說(shuō)明這是最后一組(也可能僅能拆成一個(gè)集合 下標(biāo)0 + 1 == 集合數(shù)量 1)
                if ((i + 1) == sum) {
                    //截取的下標(biāo)開(kāi)始位
                    int startIndex = (i * newSize);
                    //截取的結(jié)束下標(biāo)位置
                    int endIndex = size;
                    //插入
                    result = mtTaskMapper.insertList(taskList.subList(startIndex, endIndex));
                } else {
                    //截取的下標(biāo)開(kāi)始位
                    int startIndex = (i * newSize);
                    //截取的結(jié)束下標(biāo)位置
                    int endIndex = (i + 1) * newSize;
                    result = mtTaskMapper.insertList(taskList.subList(startIndex, endIndex));
                }
            }

=還有一種就是達(dá)到我們限制的數(shù)量就插入

@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();
            }
        }
}

總結(jié)

到此這篇關(guān)于MyBatis實(shí)現(xiàn)批量插入的文章就介紹到這了,更多相關(guān)MyBatis批量插入內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java學(xué)習(xí)DongTai被動(dòng)型IAST工具部署過(guò)程

    java學(xué)習(xí)DongTai被動(dòng)型IAST工具部署過(guò)程

    被動(dòng)型IAST被認(rèn)為是DevSecOps測(cè)試階段實(shí)現(xiàn)自動(dòng)化安全測(cè)試的最佳工具,而就在前幾天,洞態(tài)IAST正式開(kāi)源了,這對(duì)于甲方構(gòu)建安全工具鏈來(lái)說(shuō),絕對(duì)是一個(gè)大利好
    2021-10-10
  • RocketMQ中的消息發(fā)送與消費(fèi)詳解

    RocketMQ中的消息發(fā)送與消費(fèi)詳解

    這篇文章主要介紹了RocketMQ中的消息發(fā)送與消費(fèi)詳解,RocketMQ是一款高性能、高可靠性的分布式消息中間件,消費(fèi)者是RocketMQ中的重要組成部分,消費(fèi)者負(fù)責(zé)從消息隊(duì)列中獲取消息并進(jìn)行處理,需要的朋友可以參考下
    2023-10-10
  • java發(fā)送http get請(qǐng)求的兩種方式

    java發(fā)送http get請(qǐng)求的兩種方式

    這篇文章主要為大家詳細(xì)介紹了java發(fā)送http get請(qǐng)求的兩種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Java語(yǔ)言Consistent Hash算法學(xué)習(xí)筆記(代碼示例)

    Java語(yǔ)言Consistent Hash算法學(xué)習(xí)筆記(代碼示例)

    這篇文章主要介紹了Java語(yǔ)言Consistent Hash算法學(xué)習(xí)筆記(代碼示例),分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • Java數(shù)據(jù)結(jié)構(gòu)之線索化二叉樹(shù)的實(shí)現(xiàn)

    Java數(shù)據(jù)結(jié)構(gòu)之線索化二叉樹(shù)的實(shí)現(xiàn)

    在二叉樹(shù)的結(jié)點(diǎn)上加上線索的二叉樹(shù)稱為線索二叉樹(shù),對(duì)二叉樹(shù)以某種遍歷方式進(jìn)行遍歷,使其變?yōu)榫€索二叉樹(shù)的過(guò)程稱為對(duì)二叉樹(shù)進(jìn)行線索化。本文將詳解如何實(shí)現(xiàn)線索化二叉樹(shù),需要的可以參考一下
    2022-05-05
  • 一個(gè)簡(jiǎn)單的SpringBoot項(xiàng)目快速搭建詳細(xì)步驟

    一個(gè)簡(jiǎn)單的SpringBoot項(xiàng)目快速搭建詳細(xì)步驟

    Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來(lái)簡(jiǎn)化新Spring應(yīng)用的初始搭建以及開(kāi)發(fā)過(guò)程,下面這篇文章主要給大家介紹了一個(gè)簡(jiǎn)單的SpringBoot項(xiàng)目快速搭建詳細(xì)步驟,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • SpringMvc直接接收json數(shù)據(jù)自動(dòng)轉(zhuǎn)化為Map的實(shí)例

    SpringMvc直接接收json數(shù)據(jù)自動(dòng)轉(zhuǎn)化為Map的實(shí)例

    今天小編就為大家分享一篇SpringMvc直接接收json數(shù)據(jù)自動(dòng)轉(zhuǎn)化為Map的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • 詳解使用JavaMailSender給曾經(jīng)心愛(ài)的她再中秋發(fā)送一封特別的郵件

    詳解使用JavaMailSender給曾經(jīng)心愛(ài)的她再中秋發(fā)送一封特別的郵件

    網(wǎng)站的服務(wù)端向用戶發(fā)郵件時(shí),郵件中往往需要攜帶圖片,鏈接等內(nèi)容。所以為了方便起見(jiàn),我們一般發(fā)送HTML格式的郵件,那么怎么去拼一個(gè)HTML格式的郵件呢?——Thymeleaf。開(kāi)始之前,先新建一個(gè)SpringBoot項(xiàng)目,并添加需要用到的依賴。然后就可以繼續(xù)往下了
    2022-09-09
  • Java進(jìn)階:JNI使用技巧點(diǎn)滴

    Java進(jìn)階:JNI使用技巧點(diǎn)滴

    Java進(jìn)階:JNI使用技巧點(diǎn)滴...
    2006-12-12
  • Java 線程池核心參數(shù)、執(zhí)行流程與實(shí)戰(zhàn)建議全解析

    Java 線程池核心參數(shù)、執(zhí)行流程與實(shí)戰(zhàn)建議全解析

    主要介紹了 Java 線程池:核心參數(shù)、執(zhí)行流程與實(shí)戰(zhàn)建議,我將用最通俗的方式帶你搞懂 Java 線程池,從構(gòu)造函數(shù)開(kāi)始,講透執(zhí)行機(jī)制、參數(shù)配置,再結(jié)合我在真實(shí)項(xiàng)目中的使用經(jīng)驗(yàn),總結(jié)出一套實(shí)戰(zhàn)建議,需要的朋友可以參考下
    2025-04-04

最新評(píng)論

泸水县| 荣成市| 常熟市| 荣昌县| 洞口县| 威海市| 沙雅县| 申扎县| 苏尼特左旗| 绍兴市| 屯昌县| 信阳市| 襄汾县| 陆河县| 肥城市| 肥城市| 资源县| 锦州市| 汤原县| 大田县| 永修县| 玉山县| 中方县| 资源县| 县级市| 靖西县| 宁强县| 贵定县| 新邵县| 江都市| 东丽区| 青铜峡市| 木兰县| 凉山| 永昌县| 神木县| 蒙自县| 多伦县| 西和县| 应城市| 巨野县|