使用SpEL表達式來獲取SpringData Jpa在更新數據時傳遞的對象參數的屬性

一、問題描述

        使用Jpa時我們經常需要對數據庫中的數據進行更新操作,通常更新數據庫的數據有兩種方法。

        第一種是通過Jpa的實體管理器對託管態實體對象進行更新,對託管態實體對象的更新即意味着對數據庫對應記錄的更新。這種方法雖然使用起來比較簡單,但也存在全字段更新、意料之外的記錄更新、業務層跟持久層職責不清等問題。示例如下:

@Override
@Transactional(value = "demo2TransactionManager",rollbackFor = CustomException.class)
public void save6(UserInfo userInfo) throws CustomException {
    UserInfo userInfo1 = this.userInfoRepository.findById(userInfo.getOid()).get();
    userInfo1.setState(1);
    userInfo1.setUserInfoDesc("使用實體管理器對託管態用戶信息進行更新");
}

        第二種就是通過寫本地Sql的方式來實現數據庫記錄的更新,這種方雖然使用起來比較直觀,但更新時往往會傳入一個參數列表,以確定要更新的字段以及更新的條件。如下所示:

//更新用戶信息表的狀態和描述(使用參數列表)
@Query(value = "update user_info set state=:state,user_info_desc=:userInfoDesc where oid =:oid",nativeQuery = true)
@Modifying
int updateUserInfo(@Param("state") Integer state, @Param("userInfoDesc") String userInfoDesc,@Param("oid")Long oid);

        通過參數列表的方法進行更新時,一旦參數列表的個數和順序發生了變化,就會導致業務層和持久層的代碼都要進行修改,項目的可維護性和可擴展性就會變的比較差。所以,爲了解決這個問題自然我們能想到的最簡單方法就是傳一個對象作爲參數。

二、解決方法

        對於上面的問題,我們可以使用Spring在3.0版本中增加的SpEL表達式來解決。首先更新方法傳遞一個對象參數,然後使用SpEL表達式從對象中動態獲取已經設置的屬性的值,最後再動態組裝本地Sql。具體示例如下:

//更新用戶信息表的狀態和描述(使用參數對象)
@Query(value = "update user_info set state=:#{#userInfo.state},user_info_desc=:#{#userInfo.userInfoDesc} where oid =:#{#userInfo.oid}",nativeQuery = true)
@Modifying
int updateUserInfo(@Param("userInfo") UserInfo userInfo);

官方文檔參考鏈接:Spring官方示例文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章