有一個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>