欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mybatis批量更新與插入方式

 更新時(shí)間:2024年08月05日 09:43:31   作者:消碼哥  
這篇文章主要介紹了mybatis批量更新與插入方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

引言

當(dāng)我們?cè)谑褂胢ybatis的時(shí)候,可能會(huì)遇到批量插入和更新數(shù)據(jù)的問(wèn)題。

如果數(shù)據(jù)一條一條的更新或插入,那么每一條數(shù)據(jù)都會(huì)涉及到一次數(shù)據(jù)庫(kù)的操作,包括操作網(wǎng)絡(luò)IO以及磁盤(pán)IO,可想而知,效率是非常低下的。

現(xiàn)在我們都很少直接使用原生的jdbc操作數(shù)據(jù)庫(kù),而是使用比較成熟的ORM框架,現(xiàn)在就讓我們一起來(lái)學(xué)習(xí),如何使用mybatis批量更新和插入數(shù)據(jù)。

批量模式

總下來(lái)批量處理共有兩種模式,foreach動(dòng)態(tài)標(biāo)簽拼接SQL語(yǔ)句和使用BatchExecutor批處理器

foreach拼接SQL

在mybatis的xml文件中,使用foreach循環(huán)動(dòng)態(tài)標(biāo)簽拼接SQL語(yǔ)句。程序會(huì)將拼接好的一長(zhǎng)串SQL一次性發(fā)送給數(shù)據(jù)庫(kù)執(zhí)行,只需要進(jìn)行一次網(wǎng)絡(luò)IO,大大提高了執(zhí)行效率。

批量插入

拼接類似于如下的SQL語(yǔ)句:

INSERT tmp_user(user_code,user_name)VALUES('1001','張三'),('1002','李四'),('1003','王二')

實(shí)例:

<insert id="insertUser">
	INSERT INTO tmp_user(user_code,user_name) VALUES
	<foreach item="item" index="index" collection="list"  separator=",">
		(#{item.userCode},#{item.userName})
	</foreach>
</insert>

注意:

mybatis對(duì)批量插入的數(shù)據(jù)量主要是mysql自身對(duì)接收數(shù)據(jù)量的大小限制,通過(guò)參數(shù)max_allowed_packet控制

  • 查詢當(dāng)前大?。?/li>
select @@max_allowed_packet;
  • 修改為256M:
SET GLOBAL max_allowed_packet=268435456;

批量更新

使用foreach循環(huán)動(dòng)態(tài)標(biāo)簽拼接,使每一條數(shù)據(jù)的更新對(duì)應(yīng)一條update語(yǔ)句,多條update語(yǔ)句之間使用";"號(hào)進(jìn)行拼接。

實(shí)例一:

<update id="updateBatchUserById">
	<foreach item="item" index="index" collection="list" separator=";">
		UPDATE tmp_user SET user_code = #{userCode},user_name = #{userName} WHERE id = #{id}
	</foreach>
</update>
  • 拼接結(jié)果:
UPDATE tmp_user SET user_code = '1001',user_name = '張三' WHERE id = 1;UPDATE tmp_user SET user_code = '1002',user_name = '李四' WHERE id = 2;UPDATE tmp_user SET user_code = '1003',user_name = '王五' WHERE id = 3;

注意,默認(rèn)情況下,數(shù)據(jù)庫(kù)是不支持執(zhí)行這樣由";“號(hào)拼接的長(zhǎng)串的,執(zhí)行的時(shí)候會(huì)報(bào)錯(cuò),提示說(shuō)執(zhí)行的SQL有語(yǔ)法錯(cuò)誤。

我們需要通過(guò)在數(shù)據(jù)庫(kù)連接URL中指定allowMultiQueries參數(shù)值為true告訴數(shù)據(jù)庫(kù)以支持”;"號(hào)分隔的多條語(yǔ)句的執(zhí)行。

spring.datasource.url=jdbc:mysql://localhost:3306/test?allowMultiQueries=true

實(shí)例二:

<update id="updateBatchUserById">
	UPDATE tmp_user(user_code,user_name)
	<trim prefix="set" suffixOverrides=",">
		<trim prefix=" user_code = CASE " suffix=" end, ">
			<foreach collection="list" item="item">
				<if test="item.userCode != null">
					WHEN id = #{item.id} THEN #{item.userCode}
				</if>
			</foreach>
		</trim>
		<trim prefix=" user_name = CASE " suffix=" end, ">
			<foreach collection="list" item="item">
				<if test="item.userName != null">
					WHEN id = #{item.id} THEN #{item.userName}
				</if>
			</foreach>
		</trim>
	</trim>
	WHERE
	id IN
	<foreach collection="list" item="item" open="(" close=")" separator=",">
		#{item.id}
	</foreach>
</update>
  • 拼接結(jié)果:
UPDATE tmp_user 
SET user_code =
CASE
		WHEN id = 1 THEN '1001' 
		WHEN id = 2 THEN '1002' 
		WHEN id = 3 THEN '1003' 
	END,
	user_name =
CASE
	WHEN id = 1 THEN '張三'
	WHEN id = 2 THEN '李四'
	WHEN id = 3 THEN '王五'
END 
WHERE id IN (1,2,3)

可以發(fā)現(xiàn),如果批量數(shù)據(jù)量太大,要更新的字段太多,那這個(gè)SQL就會(huì)非常難看且復(fù)雜,充斥大量的case when判斷,而且這種case when感覺(jué)也會(huì)增大數(shù)據(jù)庫(kù)壓力,因?yàn)檫@種case when都需要數(shù)據(jù)庫(kù)自己去做判斷,所以個(gè)人感覺(jué)不太好,所以不推薦。

BatchExecutor批處理

MyBatis 提供了 BatchExecutor 批處理器,可以在一次數(shù)據(jù)庫(kù)會(huì)話中批量執(zhí)行多個(gè) SQL 語(yǔ)句。

這種方式需要在代碼中手動(dòng)創(chuàng)建批處理器或配置文件配置一下,并調(diào)用 batch 方法執(zhí)行批量更新。

注意,此方式可能不支持所有數(shù)據(jù)庫(kù),因此請(qǐng)仔細(xì)查閱文檔以確認(rèn)你的數(shù)據(jù)庫(kù)是否支持。

手動(dòng)創(chuàng)建批處理器

SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
 
YourMapper mapper = sqlSession.getMapper(YourMapper.class);
try {
    for (YourEntity entity : entities) {
        mapper.update(entity);
    }
    sqlSession.commit();
} finally {
    sqlSession.close();
}

實(shí)例

  • mapper 方法
int updateSupNumber(@Param("supNumber") String supNumber, @Param("id") Long putOrerId);
  • xml配置:
<update id="updateSupNumber">
	UPDATE air_put_order SET sup_number = #{supNumber} WHERE id = #{id}
</update>
  • service方法:
 @Override
    public int updateBuyPrice(JSONObject form) {
        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);
        int result = 0;
        try {
            airPutOrderGoodsSMapper = session.getMapper(AirPutOrderGoodsMapper.class);
            JSONArray prices = form.getJSONArray("prices");
            for(int i = 0;i<prices.size();i++){
                JSONObject jsonObject = prices.getJSONObject(i);
                airPutOrderGoodsSMapper.updateBuyPrice(jsonObject);
            }
            String supNumber = form.getString("supNumber");
            Long putOrerId = form.getLong("puOrderId");
            result = airPutOrderGoodsSMapper.updateSupNumber(supNumber,putOrerId);
            session.commit();
        }finally {
            session.close();
        }
        return result;
    }

自動(dòng)創(chuàng)建批處理器

在配置文件中配置一下default-executor-type: batch即可

# MyBatis配置
mybatis:
  configuration:
    default-executor-type: batch
  • service方法:

airPutOrderGoodsSMapper 使用自動(dòng)注入的對(duì)象就可以了,不需要手動(dòng)創(chuàng)建。

@Override
@Transactional
public int updateBuyPrice(JSONObject form) {
      JSONArray prices = form.getJSONArray("prices");
      for(int i = 0;i<prices.size();i++){
          JSONObject jsonObject = prices.getJSONObject(i);
          airPutOrderGoodsSMapper.updateBuyPrice(jsonObject);
      }
      String supNumber = form.getString("supNumber");
      Long putOrerId = form.getLong("puOrderId");
      int result = airPutOrderGoodsSMapper.updateSupNumber(supNumber,putOrerId);
  return result;
}

總結(jié)

foreach模式批量插入模式與MyBatis中Batch模式對(duì)比差異:

1.二者速度差異不大,for模式使用簡(jiǎn)單,Batch模式使用復(fù)雜

2.如果mysql自身對(duì)接收數(shù)據(jù)量有大小限制,建議使用Batch模式

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java8中parallelStream性能測(cè)試及結(jié)果分析

    java8中parallelStream性能測(cè)試及結(jié)果分析

    本篇文章給大家用代碼實(shí)例做了segmentfaultjava8中parallelStream性能測(cè)試,并對(duì)測(cè)試結(jié)果做了說(shuō)明,需要的朋友學(xué)習(xí)下吧。
    2018-01-01
  • spring自定義一個(gè)簡(jiǎn)單的Starter啟動(dòng)器

    spring自定義一個(gè)簡(jiǎn)單的Starter啟動(dòng)器

    這篇文章主要介紹了spring自定義一個(gè)簡(jiǎn)單的Starter啟動(dòng)器,一個(gè) starter其實(shí)就是對(duì)一個(gè)功能的集成封裝,然后對(duì)外提供一個(gè)依賴,讓業(yè)務(wù)去使用,像我們熟悉的 Redis,mongo,mybatis 等均屬于,需要的朋友可以參考下
    2023-07-07
  • Java 創(chuàng)建PDF打印小冊(cè)子案例

    Java 創(chuàng)建PDF打印小冊(cè)子案例

    這篇文章主要給大家分享Java 創(chuàng)建PDF打印小冊(cè)子案例,PDF打印小冊(cè)子是指將PDF格式文檔在打印成刊物前需要提前進(jìn)行的頁(yè)面排版,以便在打印后裝訂成冊(cè),下面文章內(nèi)容我們將下面以Java代碼展示如何來(lái)實(shí)現(xiàn),需要的朋友可以參考一下
    2021-10-10
  • Spring Cloud中Eureka開(kāi)啟密碼認(rèn)證的實(shí)例

    Spring Cloud中Eureka開(kāi)啟密碼認(rèn)證的實(shí)例

    這篇文章主要介紹了Spring Cloud中Eureka開(kāi)啟密碼認(rèn)證的實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 解決maven build 無(wú)反應(yīng),直接terminated的問(wèn)題

    解決maven build 無(wú)反應(yīng),直接terminated的問(wèn)題

    下面小編就為大家?guī)?lái)一篇解決maven build 無(wú)反應(yīng),直接terminated的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Java實(shí)現(xiàn)JSP在Servelt中連接Oracle數(shù)據(jù)庫(kù)的方法

    Java實(shí)現(xiàn)JSP在Servelt中連接Oracle數(shù)據(jù)庫(kù)的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)JSP在Servelt中連接Oracle數(shù)據(jù)庫(kù)的方法,需要的朋友可以參考下
    2014-07-07
  • Sentinel自定義異常的三種實(shí)現(xiàn)方式

    Sentinel自定義異常的三種實(shí)現(xiàn)方式

    Spring Cloud Alibaba Sentinel 是目前主流并開(kāi)源的流量控制和系統(tǒng)保護(hù)組件,Spring Cloud Alibaba Sentinel 有 3 種自定義異常的實(shí)現(xiàn)方式,本文小編將通過(guò)代碼示例給大家詳細(xì)的介紹這三種實(shí)現(xiàn)方式,需要的朋友可以參考下
    2023-11-11
  • SpringBoot接收J(rèn)SON類型的參數(shù)方式

    SpringBoot接收J(rèn)SON類型的參數(shù)方式

    這篇文章主要介紹了SpringBoot接收J(rèn)SON類型的參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • JSP 開(kāi)發(fā)之hibernate的hql查詢多對(duì)多查詢

    JSP 開(kāi)發(fā)之hibernate的hql查詢多對(duì)多查詢

    這篇文章主要介紹了JSP 開(kāi)發(fā)之hibernate的hql查詢多對(duì)多查詢的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • java8新特性之stream流中reduce()求和知識(shí)總結(jié)

    java8新特性之stream流中reduce()求和知識(shí)總結(jié)

    今天帶大家回顧Java8的新特性,文中對(duì)stream流中reduce()求和的相關(guān)知識(shí)作了詳細(xì)的介紹,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05

最新評(píng)論