二話不說,先把@DynamicUpdate的官方api-doc呈出來(以下圖),參見https://docs.jboss.org/hibernate/stable/orm/javadocs/ 前端
翻譯成白話文:先說明一下@DynamicUpdate註解用在實體類上java
有數據庫表tbl_foo和對應的實體類Foo,以下:web
id | name | col3 | col4 | col5 |
---|---|---|---|---|
1 | 畢加索 | 1770 | 奧地利 | 男 |
class Foo{
private Integer id;
private String name;
private String col3;
private String col4;
private String col5;
getter...
setter...
}
複製代碼
在Service中更新id=1記錄的name屬性,代碼以下:sql
Foo foo = fooDao.findById(1);
foo.setName("貝多芬");
fooDao.save(foo);
複製代碼
兩種狀況:數據庫
update tbl_foo set name=?, col3=?, col4=?, col5=? where id=?
複製代碼
update tbl_foo set name=? where id=?
複製代碼
以上兩種狀況對數據庫更新的結果是等效的,可是使用@DynamicUpdate性能會好一些。由於不使用@DynamicUpdate時,即便沒有改變的字段也會被更新。若是進行頻繁的更新操做,而且每次只更新少數字段,那麼@DynamicUpdate對性能的優化效果仍是很好的。api
咱們常有一種需求,web層用對象接收前端要修改的屬性值(不修改的值爲空),咱們但願直接調用dao的update方法進行選擇更新。性能
web層使用對象接收前端要修改的屬性值,可等效看作執行以下代碼:學習
Foo foo = new Foo(); foo.setId(1); foo.setName("貝多芬"); 複製代碼
這時服務層直接使用這個對象進行更新優化
fooDao.update(foo); 複製代碼
咱們期待的結果:spa
id name col3 col4 col5 1 貝多芬 1770 奧地利 男
看到網上有些文章說在實體類加上@DynamicUpdate,就能夠知足咱們的以上需求,可是很遺憾,否則!
反而獲得這樣的結果是:
id | name | col3 | col4 | col5 |
---|---|---|---|---|
1 | 貝多芬 |
只要徹底理解了api-doc中對@DynamicUpdat的說明,就很容易知道獲得這個結果的緣由了。@DynamicUpdate的動態更新的含義是,比較更新要使用的實體類中的字段值與從數據庫中查詢出來的字段值,判斷其是否有修改。看這個例子,數據庫中id=1的記錄全部字段都是非空的,可是實體類中只有name有值,也就是全部字段都變了,只是其餘字段被更新爲了新的空值。
學習一個註解(或者類)的用法,無論是開源的仍是商業的,最簡單、最靠譜、最直接的途徑就是一手的官方api文檔。
有些小哥哥在使用Spring Data JPA時用到了@DynamicUpdate,就理算固然的認爲它和Spring是一家,其實否則。其實從引用註解時的包名就能看出來,很明顯Hibernate纔是它的原配。緣由固然就是Spring Data JPA使用的ORM實現是Hibernate。因此也就解釋了上圖中的文檔是Hibernate的api文檔,而不是Spring或者Java的api文檔。
以上所有爲我的觀點,但願對你有幫助。本人水平有限,不免有不妥或者謬誤之處,望你們指出。有其餘問題也歡迎和你們交流!