對(duì)于 Spring Data JPA 進(jìn)行指定字段進(jìn)行更新時(shí),可以使用下列代碼
@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);
首先讓人奇怪的是,repository method只能返回int或者轉(zhuǎn)為void,因?yàn)檫@個(gè)操作只會(huì)把數(shù)據(jù)寫(xiě)入到數(shù)據(jù)庫(kù),但是不會(huì)select。
執(zhí)行完modifying query, EntityManager可能會(huì)包含過(guò)時(shí)的數(shù)據(jù),因?yàn)镋ntityManager不會(huì)自動(dòng)清除實(shí)體。
只有添加clearAutomatically屬性,EntityManager才會(huì)自動(dòng)清除實(shí)體對(duì)象。
@Modifying(clearAutomatically = true)
@Query("update RssFeedEntry feedEntry set feedEntry.read =:isRead where feedEntry.id =:entryId")
void markEntryAsRead(@Param("entryId") Long rssFeedEntryId, @Param("isRead") boolean isRead);
這樣是一個(gè)解決方案,當(dāng)然也可以使用動(dòng)態(tài)更新。在實(shí)體類(lèi)上加上注解@DynamicUpdate, @DynamicInsert,這兩個(gè)注解是jpa的實(shí)現(xiàn)hibernate才有的,當(dāng)jpa的實(shí)現(xiàn)為hibernate時(shí),才會(huì)生效,當(dāng)有以上注解時(shí),標(biāo)記實(shí)體sql動(dòng)態(tài)生成,當(dāng)insert的時(shí)候,如果字段為NULL,則生成的sql語(yǔ)句不插入該字段,當(dāng)update時(shí),如果字段為NULL,則不生成update該字段,前提條件的是,當(dāng)DynamicUpdate時(shí),需要先執(zhí)行select然后在update。
但是需要注意的是,當(dāng)你select后,顯示的把某些字段set為NULL,jpa為認(rèn)為你修改了該字段,同樣會(huì)生成到update語(yǔ)句中,所以動(dòng)態(tài)的update只是為讓update的sql語(yǔ)句減少不必要的null設(shè)置,并不能達(dá)到自己想要自定義的update。