mybatis批量添加,批量更新之前如何判斷是否已經(jīng)存在
批量添加,批量更新之前判斷是否已經(jīng)存在
批量添加之前判斷是否已經(jīng)存在,foreach separator用UNION ALL。
批量修改
批量更新update詳解文檔
1 更新單條記錄
UPDATE course SET name = ‘course1' WHEREid = ‘id1';
2 更新多條記錄的同一個字段為同一個值
UPDATE course SET name=‘course1' WHERE id in(‘id1',‘id2','id3);
3 更新多條記錄為多個字段為不同的值
比較普通的寫法,是通過循環(huán),依次執(zhí)行update語句。
Mybatis寫法如下:
<update id="updateBatch" ?parameterType="java.util.List"> ? ? ? <foreach collection="list" item="item" index="index" open="" close="" separator=";"> ? ? ? ? update course ? ? ? ? <set> ? ? ? ? ? ? name=${item.name} ? ? ? ? </set> ? ? ? ? where id = ${item.id} ? ? </foreach> ? ? ? </update>
一條記錄update一次,性能比較差,容易造成阻塞。
MySQL沒有提供直接的方法來實現(xiàn)批量更新,但可以使用case when語法來實現(xiàn)這個功能。
UPDATE course ? ? SET name = CASE id? ? ? ? ? WHEN 1 THEN 'name1' ? ? ? ? WHEN 2 THEN 'name2' ? ? ? ? WHEN 3 THEN 'name3' ? ? END,? ? ? title = CASE id? ? ? ? ? WHEN 1 THEN 'New Title 1' ? ? ? ? WHEN 2 THEN 'New Title 2' ? ? ? ? WHEN 3 THEN 'New Title 3' ? ? END WHERE id IN (1,2,3)
這條sql的意思是,如果id為1,則name的值為name1,title的值為New Title1;依此類推。
在Mybatis中的配置則如下:
?<update id="updateBatch"parameterType="list"> ? ? ? ? ? ? update course ? ? ? ? ? ? <trim prefix="set" suffixOverrides=","> ? ? ? ? ? ? ?<trim prefix="name=case" suffix="end,"> ? ? ? ? ? ? ? ? ?<foreach collection="list" item="item" index="index"> ? ? ? ? ? ? ? ? ? ? ? ? ?<if test="item.name!=null"> ? ? ? ? ? ? ? ? ? ? ? ? ? when id=#{item.id} then #{item.name} ? ? ? ? ? ? ? ? ? ? ? ? ?</if> ? ? ? ? ? ? ? ? ?</foreach> ? ? ? ? ? ? ? </trim> ? ? ? ? ? ? ? <trim prefix="title =case" suffix="end,"> ? ? ? ? ? ? ? ? ?<foreach collection="list" item="item" index="index"> ? ? ? ? ? ? ? ? ? ? ? ? ?<if test="item.title!=null"> ? ? ? ? ? ? ? ? ? ? ? ? ? when id=#{item.id} then #{item.title} ? ? ? ? ? ? ? ? ? ? ? ? ?</if> ? ? ? ? ? ? ? ? ?</foreach> ? ? ? ? ? ? ? </trim> ? ? ? ? ? ? ?</trim> ? ? ? ? ? ? where ? ? ? ? ? ? <foreach collection="list" separator="or" item="item" index="index"> ? ? ? ? ? ? ? id=#{item.id} ? ? ? ? ? </foreach> </update>
屬性說明
- 1.prefix,suffix 表示在trim標(biāo)簽包裹的部分的前面或者后面添加內(nèi)容
- 2.如果同時有prefixOverrides,suffixOverrides 表示會用prefix,suffix覆蓋Overrides中的內(nèi)容。
- 3.如果只有prefixOverrides,suffixOverrides 表示刪除開頭的或結(jié)尾的xxxOverides指定的內(nèi)容。
4 sql批量更新
看另外一個示例:
? ?<update id="updateBatch"parameterType="java.util.List"> ? ? update mydata_table? ? ? set ?status= ? ? <foreach collection="list" item="item" index="index"? ? ? ? ? separator=" " open="case ID" close="end"> ? ? ? ? when #{item.id} then #{item.status} ? ? </foreach> ? ? where id in ? ? <foreach collection="list" index="index" item="item"? ? ? ? ? separator="," open="(" close=")"> ? ? ? ? #{item.id,jdbcType=BIGINT} ? ? </foreach> ?</update>
其中when…then…是sql中的"switch" 語法。這里借助mybatis的語法來拼湊成了批量更新的sql,上面的意思就是批量更新id在updateBatch參數(shù)所傳遞List中的數(shù)據(jù)的status字段。還可以使用實現(xiàn)同樣的功能,代碼如下:
<update id="updateBatch" parameterType="java.util.List"> ? ? ? ? update mydata_table ? ? ? ? <trim prefix="set" suffixOverrides=","> ? ? ? ? ? ? <trim prefix="status =case" suffix="end,"> ? ? ? ? ? ? ? ? <foreach collection="list" item="item" index="index"> ? ? ? ? ? ? ? ? ? ? ?when id=#{item.id} then #{item.status} ? ? ? ? ? ? ? ? </foreach> ? ? ? ? ? ? </trim> ? ? ? ? </trim> ? ? ? ? where id in ? ? ? ? <foreach collection="list" index="index" item="item" separator="," open="(" close=")"> ? ? ? ? ? ? #{item.id,jdbcType=BIGINT} ? ? ? ? </foreach> </update>
其結(jié)構(gòu)如下:
? ? update mydata_table? ? ? set status =? ? ? case ? ? ? ? when id = #{item.id} then #{item.status}//此處應(yīng)該是<foreach>展開值 ? ? ? ? ... ? ? end ? ? where id in (...);
如果對要更新的數(shù)據(jù)進(jìn)行判斷,只有符合條件的數(shù)據(jù)才能進(jìn)行更新,這種情況可以這么做:
<trim prefix="status =case" suffix="end,"> ? ? ?<foreach collection="list" item="item" index="index"> ? ? ? ? ?<if test="item.status !=null and item.status != -1"> ? ? ? ? ? ? ?when id=#{item.id} then #{item.status} ? ? ? ? ?</if> ? ? ?</foreach> </trim>
這樣的話只有要更新的list中status != null && status != -1的數(shù)據(jù)才能進(jìn)行status更新.其他的將使用默認(rèn)值更新,而不會保持原數(shù)據(jù)不變.如果要保持原數(shù)據(jù)不變呢?
即滿足條件的更新,不滿足條件的保持原數(shù)據(jù)不變,簡單的來做就是再加一個,因為mybatis中沒有if…else…語法,但可以通過多個實現(xiàn)同樣的效果,如下:
<trim prefix="status =case" suffix="end,"> ? ? ?<foreach collection="list" item="item" index="index"> ? ? ? ? ?<if test="item.status !=null and item.status != -1"> ? ? ? ? ? ? ?when id=#{item.id} then #{item.status} ? ? ? ? ?</if> ? ? ? ? ?<if test="item.status == null or item.status == -1"> ? ? ? ? ? ? ?when id=#{item.id} then mydata_table.status ? ? ?//這里就是原數(shù)據(jù) ? ? ? ? ?</if> ? ? ?</foreach> </trim>
整體批量更新的寫法如下:
<update id="updateBatch"parameterType="java.util.List"> ? ? ? ? update mydata_table ? ? ? ? <trim prefix="set" suffixOverrides=","> ? ? ? ? ? ? <trim prefix="status =case" suffix="end,"> ? ? ? ? ? ? ? ? ?<foreach collection="list" item="item" index="index"> ? ? ? ? ? ? ? ? ? ? ?<if test="item.status !=null and item.status != -1"> ? ? ? ? ? ? ? ? ? ? ? ? ?when id=#{item.id} then #{item.status} ? ? ? ? ? ? ? ? ? ? ?</if> ? ? ? ? ? ? ? ? ? ? ?<if test="item.status == null or item.status == -1"> ? ? ? ? ? ? ? ? ? ? ? ? ?when id=#{item.id} then mydata_table.status//原數(shù)據(jù) ? ? ? ? ? ? ? ? ? ? ?</if> ? ? ? ? ? ? ? ? ?</foreach> ? ? ? ? ? ? </trim> ? ? ? ? </trim> ? ? ? ? where id in ? ? ? ? <foreach collection="list" index="index" item="item" separator="," open="(" close=")"> ? ? ? ? ? ? #{item.id,jdbcType=BIGINT} ? ? ? ? </foreach> </update>
1.組裝多個update語句,這種方式需要設(shè)置jdbc連接 allowMultiQueries=true
? ?<update id="updateEquementWaterTest" ? parameterType="java.util.List"> ?? ? ? ? <foreach collection="list" item="item" index="index"> ?? ??? ??? ??? ? ? ? ? ? ??? ?update rent_hl_room l ?? ??? ??? ??? ?SET l.water_meter_id=#{item.equipmentCode}, ?? ??? ??? ??? ?l.water_meter_source_type=#{item.equipmentSource} ?? ??? ??? ??? ?WHERE? ?? ??? ??? ??? ? ? ?l.room_id=#{item.roomId}; ? ? ?? ??? ? </foreach> ? ? ?</update>
2.case when
UPDATE? ? rent_hl_room l? SET ? electricity_meter_id =? ? CASE ? ? WHEN room_id = 1942 ? ? THEN 180524348? ? ? WHEN room_id = 1945 ? ? THEN 180524480? ? END, ? electricity_meter_source_type =? ? CASE ? ? WHEN room_id = 1942? ? ? THEN ym? ? ? WHEN room_id = 1945? ? ? THEN ym? ? END? WHERE room_id = 1942? ? OR room_id = 1945?
? ? ? ? ? <update id="updateEquementWater" ? parameterType="java.util.List"> ?? ? ? ? ? ? ?update rent_hl_room l ? ? ? ? ? ? <trim prefix="set" suffixOverrides=","> ? ? ? ? ? ? ?<trim prefix="water_meter_id =case" suffix="end,"> ? ? ? ? ? ? ? ? ?<foreach collection="list" item="i" index="index"> ? ? ? ? ? ? ? ? ? ? ? ? ?<if test="i.equipmentCode!=null"> ? ? ? ? ? ? ? ? ? ? ? ? ? when room_id=#{i.roomId} then #{i.equipmentCode} ? ? ? ? ? ? ? ? ? ? ? ? ?</if> ? ? ? ? ? ? ? ? ?</foreach> ? ? ? ? ? ? ? </trim> ? ? ? ? ? ? ? <trim prefix=" water_meter_source_type =case" suffix="end,"> ? ? ? ? ? ? ? ? ?<foreach collection="list" item="i" index="index"> ? ? ? ? ? ? ? ? ? ? ? ? ?<if test="i.equipmentSource!=null"> ? ? ? ? ? ? ? ? ? ? ? ? ? when room_id=#{i.roomId} then #{i.equipmentSource} ? ? ? ? ? ? ? ? ? ? ? ? ?</if> ? ? ? ? ? ? ? ? ?</foreach> ? ? ? ? ? ? ? </trim> ? ? ? ? ? ? ?</trim> ? ? ? ? ? ? where ? ? ? ? ? ? <foreach collection="list" separator="or" item="i" index="index" > ? ? ? ? ? ? ? room_id=#{i.roomId} ? ? ? ? ? </foreach> ?? ? ? ? ? ? ? ?</update>
經(jīng)測試 100條數(shù)據(jù)的時候第一種方式的效率比第二種差不多高1倍。。。。。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring?boot詳解fastjson過濾字段為null值如何解決
這篇文章主要介紹了解決Spring?boot中fastjson過濾字段為null值的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07java實現(xiàn)微信公眾平臺自定義菜單的創(chuàng)建示例
這篇文章主要介紹了java實現(xiàn)微信公眾平臺自定義菜單的創(chuàng)建示例,需要的朋友可以參考下2014-04-04Java并發(fā)工具之CountDownLatch使用詳解
這篇文章主要介紹了Java并發(fā)工具之CountDownLatch使用詳解,通過使用 CountDownLatch可以使當(dāng)前線程阻塞,等待其他線程完成給定任務(wù),可以類比旅游團(tuán)導(dǎo)游要等待所有的游客到齊后才能去下一個景點,需要的朋友可以參考下2023-12-12Spring?Boot存在路徑遍歷漏洞CVE-2021-22118的問題解析
CVE-2021-22118?是一個在?Spring?Boot?中發(fā)現(xiàn)的漏洞,該漏洞關(guān)系到?Spring?Boot?的開發(fā)者工具(Devtools)中的遠(yuǎn)程更新(Remote?Update)功能,這篇文章主要介紹了Spring?Boot存在路徑遍歷漏洞CVE-2021-22118,需要的朋友可以參考下2023-09-09JavaEE的進(jìn)程,線程和創(chuàng)建線程的5種方式詳解
這篇文章主要為大家詳細(xì)介紹了JavaEE的進(jìn)程,線程和創(chuàng)建線程的5種方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03你知道在Java中Integer和int的這些區(qū)別嗎?
最近面試,突然被問道,說一下Integer和int的區(qū)別.額…可能平時就知道寫一些業(yè)務(wù)代碼,包括面試的一些Spring源碼等,對于這種特別基礎(chǔ)的反而忽略了,導(dǎo)致面試的時候突然被問到反而不知道怎么回答了.哎,還是乖乖再看看底層基礎(chǔ),順帶記錄一下把 ,需要的朋友可以參考下2021-06-06