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

mybatis批量更新與插入方式

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

引言

當我們在使用mybatis的時候,可能會遇到批量插入和更新數(shù)據(jù)的問題。

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

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

批量模式

總下來批量處理共有兩種模式,foreach動態(tài)標簽拼接SQL語句和使用BatchExecutor批處理器

foreach拼接SQL

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

批量插入

拼接類似于如下的SQL語句:

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

實例:

<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對批量插入的數(shù)據(jù)量主要是mysql自身對接收數(shù)據(jù)量的大小限制,通過參數(shù)max_allowed_packet控制

  • 查詢當前大小:
select @@max_allowed_packet;
  • 修改為256M:
SET GLOBAL max_allowed_packet=268435456;

批量更新

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

實例一:

<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;

注意,默認情況下,數(shù)據(jù)庫是不支持執(zhí)行這樣由";“號拼接的長串的,執(zhí)行的時候會報錯,提示說執(zhí)行的SQL有語法錯誤。

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

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

實例二:

<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ù)量太大,要更新的字段太多,那這個SQL就會非常難看且復雜,充斥大量的case when判斷,而且這種case when感覺也會增大數(shù)據(jù)庫壓力,因為這種case when都需要數(shù)據(jù)庫自己去做判斷,所以個人感覺不太好,所以不推薦。

BatchExecutor批處理

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

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

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

手動創(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();
}

實例

  • 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;
    }

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

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

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

airPutOrderGoodsSMapper 使用自動注入的對象就可以了,不需要手動創(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模式對比差異:

1.二者速度差異不大,for模式使用簡單,Batch模式使用復雜

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

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

相關(guān)文章

  • Spring Boot集成netty實現(xiàn)客戶端服務(wù)端交互示例詳解

    Spring Boot集成netty實現(xiàn)客戶端服務(wù)端交互示例詳解

    這篇文章主要給大家介紹了關(guān)于Spring Boot集成netty實現(xiàn)客戶端服務(wù)端交互的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-12-12
  • Springboot錯誤頁面和錯誤信息定制操作

    Springboot錯誤頁面和錯誤信息定制操作

    這篇文章主要介紹了Springboot錯誤頁面和錯誤信息定制操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • feign實現(xiàn)傳遞參數(shù)的三種方式小結(jié)

    feign實現(xiàn)傳遞參數(shù)的三種方式小結(jié)

    這篇文章主要介紹了feign實現(xiàn)傳遞參數(shù)的三種方式小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java?list和map切割分段的實現(xiàn)及多線程應(yīng)用案例

    java?list和map切割分段的實現(xiàn)及多線程應(yīng)用案例

    這篇文章主要為大家介紹了java?list和map切割分段的實現(xiàn)及多線程應(yīng)用案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • springMVC使用ajaxFailUpload上傳圖片的方法

    springMVC使用ajaxFailUpload上傳圖片的方法

    這篇文章主要介紹了springMVC使用ajaxFailUpload上傳圖片的相關(guān)知識,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • SpringBoot JAR和WAR方式打包并部署的詳細步驟及對比分析

    SpringBoot JAR和WAR方式打包并部署的詳細步驟及對比分析

    無論選擇JAR還是WAR部署方式,關(guān)鍵在于匹配團隊的技術(shù)棧、運維能力和業(yè)務(wù)需求,Spring Boot的靈活性支持兩種部署模式,為不同場景提供了合適的解決方案,本文給大家詳細對比分析了這兩種方式,需要的朋友可以參考下
    2026-01-01
  • Sharding-Proxy基本功能用法介紹

    Sharding-Proxy基本功能用法介紹

    這篇文章介紹了Sharding-Proxy基本功能用法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-02-02
  • 基于SpringMVC中的路徑參數(shù)和URL參數(shù)實例

    基于SpringMVC中的路徑參數(shù)和URL參數(shù)實例

    這篇文章主要介紹了基于SpringMVC中的路徑參數(shù)和URL參數(shù)實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 詳解JNA中的回調(diào)方法

    詳解JNA中的回調(diào)方法

    這篇文章主要介紹了JNA中的回調(diào)方法,主要包括JNA 中的 Callback,callback 的應(yīng)用,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • SpringBoot?集成短信和郵件的配置示例詳解

    SpringBoot?集成短信和郵件的配置示例詳解

    這篇文章主要介紹了SpringBoot?集成短信和郵件的相關(guān)知識,項目中使用lombok插件和swagger依賴,無相關(guān)依賴的請自行修改,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-04-04

最新評論

金阳县| 收藏| 大荔县| 图木舒克市| 土默特左旗| 偏关县| 徐水县| 兴业县| 宜宾县| 钟祥市| 张家界市| 内江市| 革吉县| 潍坊市| 仁化县| 濉溪县| 鹤峰县| 宁蒗| 祁连县| 堆龙德庆县| 绥宁县| 莲花县| 新余市| 龙游县| 柏乡县| 鹤峰县| 庐江县| 叶城县| 德清县| 五指山市| 沂南县| 随州市| 海林市| 邓州市| 涟水县| 庆安县| 克什克腾旗| 延津县| 桐梓县| 修武县| 类乌齐县|