鍍金池/ 問答/Java  數據庫  HTML/ 疑問: 數據庫進行更新時 當數據數據相同時 全字段更新和單字段更新是否有區(qū)別

疑問: 數據庫進行更新時 當數據數據相同時 全字段更新和單字段更新是否有區(qū)別

起因是我的代碼中更新方法和同事寫的不一樣
數據層用的mybatis,數據庫用的mysql
我的寫法

Student s= studentDao.selectById("123");
.......//業(yè)務操作
Student sTemp = new Student();
sTemp.setId("123");
sTemp.setSex(0);
studentDao.update(sTemp);

然后我同事是這么寫的

Student s= studentDao.selectById("123");
.......//業(yè)務操作
s.setId("123");
s.setSex(0);
studentDao.update(s);

那么這里有個問題在mybaits中是判斷這個字段有就會加上更新語句
數據庫原數據

id   name sex  weight
123  張三   1     120

比如這兩段代碼執(zhí)行完成后
我的sql

update Student set sex=0 where id='123';

我同事的sql

update Student set name="張三",sex=0,weight="120" where id='123';

我的做法弊端在于 new了一個對象
我自己的想法是為了節(jié)約全字段更新數據的sql執(zhí)行時間,還有mybatis的的sql拼接

問題1:
數據相同時這兩種sql有沒有性能差異?我實際測試的時候好像并沒有看出有差異,希望有人能告訴我原理

問題2:
以上兩種方法到底哪種方法才是正確的

回答
編輯回答
解夏

寫個通用的更新sql,可以用mybatis的條件語句,傳值也是傳多個值,然后不需要更新的值傳null,這樣可以避免更新的時候new一個對象,也可以避免沒有改動的數據也修改,不過可能字段多了,但是某時只需改一個字段的時候多個參數值為null,不大美觀。

2018年8月3日 05:24
編輯回答
慢半拍

可以看看這里
后端好書閱讀與推薦(續(xù)二) - QueenKing - SegmentFault
https://segmentfault.com/a/11...

更新有兩種方式,一種是通用性更新:從數據庫獲得完整對象,然后修改這個對象,然后保存,另一種是針對性更新:直接按條件修改數據庫中一些對象的某些字段。前者的好處在于通用,可以將前臺傳來的表單無論修改了那個字段都可以直接保存,無需更多拼湊,修改任何字段的方法都是相同的,便于統(tǒng)一處理,后者的好處在于性能更好,因為節(jié)省了許多不必要字段的傳遞,而且允許原子性更新,比如inc

2017年5月30日 08:04
編輯回答
久礙你

樓上大致正確,但是
1.前者也是通用的,但要多寫一些 setXXX 的代碼;

2.第二種方式在并發(fā)情況下容易導致前面的update失效,除非整個過程加鎖:
請求1:
update Student set name="李四";
請求2:
update Student set name="張三",sex=0,weight="120" where id='123';

期望結果:
name="李四",sex=0,weight="120" where id='123'
實際結果:
"張三",sex=0,weight="120" where id='123'

原因:
請求2 setXXX 時,請求1正在執(zhí)行SQL語句update1,這時候MySQL會加鎖。
等到update1執(zhí)行完后,請求2的SQL語句update2再執(zhí)行,導致原本update1修改后的
name="李四"又被update2改回了name="張三"。

所以如果要用完整更新,請求2必須在setXXX前加鎖,讓update1在update2完成后才執(zhí)行,這樣才能避免并發(fā)情況下導致前面的update失效的問題。

2017年11月30日 04:32
編輯回答
冷溫柔

首先new不new不是關鍵,當然這個new是沒必要的,關鍵是你的映射文件是如何寫的。
建議是需要更新的字段才出現的sql中。

建議你使用mbg, 會自動生成updateByPrimaryKeySelective這種方法,只更新有值的字段。

2018年7月22日 15:24