mysql和mybatis的批量更新

有一個user表:字段id,name,age

現在發現所有用戶的年齡都錄入錯誤了,然後重新蒐集到了所有用戶的年齡,現在需要將所有用戶的年齡重新更新進去;

現在有所有用戶id及其對應的age,怎麼更新比較好?

create table user(
    id int primary key AUTO_INCREMENT,
    name varchar(200) not null,
    age int
);

思路:

1 寫一個update語句:update user set age=xx where id=xx;

然後循環執行上面的update語句,比如數據有1萬條,執行一萬次sql更新。可以更新成功沒問題,但是速度會比較慢。

2 批量更新,見下面

一、MySQL

首先要知道:MySQL沒有提供直接的方法來實現批量更新,但可以使用case when語法來實現這個功能,如下語法格式:

UPDATE user
    SET age = CASE id 
        WHEN 1 THEN age1
        WHEN 2 THEN age2
        WHEN 3 THEN age3
    END, 
    name = CASE id 
        WHEN 1 THEN 'name1'
        WHEN 2 THEN 'name2'
        WHEN 3 THEN 'name3'
    END
WHERE id IN (1,2,3)

在這個例子中,具體的實現如下:

//id和正確的age都裝在一個list集合中,有所有的User對象
String sql1 = "";
String sql2 = "";
for(int i=1;i<=10000;i++){
    User user = list.get(i);
	sql1 += "when "+user.getId()+" then "+user.getAge()+" ";
	sql2 += user.getId()+",";
}
sql2 = sql2.substring(0,sql2.length()-1);//去掉最後一個","
String sql = "update test set name = case id "+sql1+" end where id in ("+sql2+")";
//打印出組裝完成的sql,最後執行該sql語句
System.out.println("sql="+sql);

二、myBatis(現在在公司裏邊基本上都使用框架,而不使用純sql語句了),實現如下:

//傳參並執行
Map<String, Object> map = new HashMap<>();
map.put("paramList",paramList);
ssqBaseDao.update("userMapping.updateAllAge", map);

//sql
<update id="updateAllAge" parameterType="java.util.HashMap">
	update analysis_ssq_base_red_blue set red_sum_omission=
	<foreach collection="paramList" item="item" index="index"
			 separator=" " open="case id" close="end">
		when #{item.id} then #{item.age}
	</foreach>
	where id in
	<foreach collection="paramList" item="item" index="index"
			 separator="," open="(" close=")">
		#{item.id}
	</foreach>
</update>

三、同樣是mybatis方式,但是是多個字段,作爲條件的字段類型不是整數,是varchar,有點不一樣,如下:

<!--
1 類型上的變化導致改變
    case id when #{item.id} then #{item.foreSumValueOmission}變成了
    case when issue_no=#{item.issueNo} then #{item.foreSumValueOmission}變成了
2 多個字段更新導致變化,加了這段即可
    back_sum_value_omission=
    <foreach collection="paramList" item="item" index="index"
		    separator=" " open="case" close="end">
	    when issue_no=#{item.issueNo} then #{item.backSumValueOmission}
    </foreach>
-->
<!--初始化前區和後區和值遺漏 fore_sum_value_omission,back_sum_value_omissio-->
<update id="initDltForeAndBackSumOmission" parameterType="java.util.HashMap">
	update analysis_dlt_base_fore_back set fore_sum_value_omission=
	<foreach collection="paramList" item="item" index="index"
			separator=" " open="case" close="end,">
		when issue_no=#{item.issueNo} then #{item.foreSumValueOmission}
	</foreach>
	back_sum_value_omission=
	<foreach collection="paramList" item="item" index="index"
			separator=" " open="case" close="end">
		when issue_no=#{item.issueNo} then #{item.backSumValueOmission}
	</foreach>
	where issue_no in
	<foreach collection="paramList" item="item" index="index"
			separator="," open="(" close=")">
		#{item.issueNo}
	</foreach>
</update>

 

發佈了101 篇原創文章 · 獲贊 9 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章