首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring Data JPA @Query 實現原生 SQL 更新操作:@Modifying + @Transactional 避坑指南

     編輯:Java 相關知識

核心註解組合

@Modifying(clearAutomatically = true)
@Transactional
@Query(value = "UPDATE info SET status = ?1 WHERE id = ?2", nativeQuery = true)
int updateStatusById(String status, String id);

三大註解詳解

註解作用缺失後果
@Query(nativeQuery = true)聲明使用原生 SQL 而非 JPQL語法報錯(JPQL 不支持 UPDATE ... SET)
@Modifying標識為修改操作(INSERT/UPDATE/DELETE)拋出 InvalidDataAccessApiUsageException:查詢方法不能修改數據
@Transactional提供事務邊界,提交變更數據不落庫(自動提交關閉時)或拋事務異常

參數綁定方式

  • 位置參數:?1, ?2... 對應方法參數順序
  • 命名參數::status, :id 配合 @Param("status")
@Query(value = "UPDATE info SET status = :status WHERE id = :id", nativeQuery = true)
int updateStatusById(@Param("status") String status, @Param("id") String id);

返回值類型選擇

返回類型含義適用場景
int / long受影響行數批量更新、需確認執行結果
void無返回不關心行數,簡單修改
boolean是否影響≥1行邏輯判斷

clearAutomatically = true 的作用

執行修改後自動清空持久化上下文(一級緩存),避免後續讀取到舊數據(髒讀)。建議始終開啟,除非極度確定後續無讀取操作。

完整 Repository 示例

public interface InfoRepository extends JpaRepository<Info, String> {
    @Modifying(clearAutomatically = true)
    @Transactional
    @Query(value = "UPDATE info SET status = ?1, update_time = NOW() WHERE id = ?2", nativeQuery = true)
    int updateStatusById(String status, String id);

    @Modifying
    @Transactional
    @Query(value = "DELETE FROM info WHERE create_time < ?1", nativeQuery = true)
    int deleteExpired(Date threshold);
}

常見坑點

  1. 忘記 @Transactional:Spring Data JPA 默認查詢方法無事務,修改必須額外添加。
  2. JPQL 寫 UPDATE:JPQL 支持 UPDATE Entity e SET e.field = ?1 WHERE e.id = ?2,但不觸發實體生命週期回調、不清理緩存,原生 SQL 更直觀可控。
  3. 大批量更新性能:單條原生 SQL 更新萬級數據極慢,應改用 @QueryHints 批處理或分頁循環更新。
  4. 樂觀鎖衝突:實體有 @Version 時,原生 SQL 更新不會自動遞增版本號,導致後續樂觀鎖失效——需手動 SET version = version + 1。

總結

Spring Data JPA 執行原生 SQL 更新鐵三角:@Query(nativeQuery=true) + @Modifying + @Transactional。返回 int 獲取影響行數,clearAutomatically=true 保證緩存一致性。大批量、樂觀鎖場景需額外關注性能與版本號維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved