日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

jpa原生query_JPA执行原生SQL语句

發布時間:2023/12/19 数据库 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jpa原生query_JPA执行原生SQL语句 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

作業的項目終于告一段落了暫時,這周繼續進行日志系統的編寫,只可惜這周開始練科三了,一開始是全天練車,導致每天寫代碼的時間減少了好多,后來時間進行了調整(早上四點半到七點半,晚上五點到七點多),也算有挺多的時間了。

(駕校不正規,練車兩行淚)

需求

由于日志系統每天的數據量較大,隨著時間的推移,有很多之前的數據可能就沒用了,但是在數據表里放著就占資源,于是要刪除三個月之前的數據,就需要自己寫原生SQL語句了。

Jdbc

按照教程給的源碼進行了功能的編寫,由于沒寫單元測試,所以雖說功能實現了,但是還是有很大的缺陷的,后來問了一下潘老師,老師推薦使用的是JPA

@Override

public List getData() {

/\* 定義實現了RowCallbackHandler接口的對象\*/

RowCallbackHandler rowCallbackHandler \= new RowCallbackHandler() {

/\*\*

\* 該方法用于執行jdbcTemplate.query后的回調,每行數據回調1次。比如DayLog表中有兩行數據,則回調此方法兩次。

\* @param resultSet 查詢結果,每次一行

\* @throws SQLException 查詢出錯時,將拋出此異常,暫時不處理。

\*/

@Override

public void processRow(ResultSet resultSet) throws SQLException {

DayLog dayLog \= new DayLog();

dayLog.setId(resultSet.getLong("id"));

dayLog.setDay(resultSet.getDate("day"));

dayLogs.add(dayLog);

logger.info(resultSet.toString());

}

};

String query \= "select \* from day\_log where \`day\` <= curdate() - interval 3 month";

jdbcTemplate.query(query,rowCallbackHandler);

return dayLogs;

}

@Override

public boolean delete()

{

String sql \= String.format("delete from day\_log where \`day\` <= curdate() - interval 3 month");

this.jdbcTemplate.update(sql);

return true;

}

}

JPA

后來找了好多博客,看了一下它的用法,發現還是挺好用的:

public interface LogRepository extends JpaRepository, JpaSpecificationExecutor {

/**

* 根據月份查找所有記錄

*

* @return

*/

@Query(value = "SELECT * FROM `log` where `timestamp` <= curdate() - interval 3 month",nativeQuery = true)

List getLogOfThreeMonth();

/**

* 根據月份刪除所有記錄

* @return

*/

@Transactional(rollbackFor = Exception.class)

@Modifying

@Query(value = "delete from log where `timestamp` <= curdate() - interval 3 month",nativeQuery = true)

void deleteLogOfThreeMonth();

}

@Query

JPA執行原生SQL語句,首先要讓倉庫繼承 JpaRepository ,然后加@Query注解,value表示要執行的語句,對于nativeQuery = true ,有的博客是這樣解釋的:

有nativeQuery = true時,是可以執行原生sql語句,所謂原生sql,也就是說這段sql拷貝到數據庫中,然后把參數值給一下就能運行了

沒有nativeQuery = true時,就不是原生sql,而其中的select * from xxx中xxx也不是數據庫對應的真正的表名,而是對應的實體名,并且sql中的字段名也不是數據庫中真正的字段名,而是實體的字段名。

@Modifying

對于該注解的解釋,官方給出的說明是這樣的:

As the queries themselves are tied to the Java method that executes them, you can actually bind them directly by using the Spring Data JPA @Query annotation

rather than annotating them to the domain class.

You can modify queries that only need parameter binding by annotating the query method with @Modifying

The @Modifying annotation is only relevant in combination with the @Query annotation. Derived query methods or custom methods do not require this Annotation.

Doing so triggers the query annotated to the method as an updating query instead of a selecting one.

由于查詢本身綁定到執行它們的Java方法,實際上可以通過使用Spring Data JPA@Query注釋直接綁定它們,而不是將它們注釋到域類。

通過使用@Modifying注釋查詢方法,可以修改只需要參數綁定的查詢

@Modifying注釋只與@Query注釋結合使用。派生查詢方法或自定義方法不需要此批注。

這樣做將觸發作為更新查詢(更新、插入、刪除)而不是選擇查詢注釋到方法的查詢。

也就是說,當我們要通過自已寫的更新、插入、刪除SQL語句來實現更新、插入、刪除操作時,至少需要用兩個步驟:

1.@Query來注入我們自定義的sql;

2.使用@Modifying來標注是一個更新類的自定義語句。

@Transactional

官方給出的說明是:.

By default, CRUD methods on repository instances are transactional. For read operations, the transaction configuration readOnly flag is set to true. All others are configured with a plain @Transactional so that default transaction configuration applies. For details, see JavaDoc of SimpleJpaRepository. If you need to tweak transaction configuration for one of the methods declared in a repository, redeclare the method in your repository interface, as follows:

_Example. Custom transaction configuration for CRUD_

默認情況下,存儲庫實例上的CRUD方法是事務性的。對于讀取操作,事務配置readOnly標志設置為true。所有其他的都配置了一個普通的@Transactional,以便應用默認的事務配置。有關詳細信息,請參見SimpleJpaRepository的JavaDoc。如果需要調整存儲庫中聲明的方法之一的事務配置,請在存儲庫界面中重新聲明該方法,如下所示:

例子。CRUD的自定義事務配置

對于更新查詢(更新(UPDATE)、刪除( DELETE))來說,都需要加@Transactional注解。

疑惑及解決

之前Repository類繼承的都是CrudRepository這個類,以實現save,delete等方法,但是為什么我繼承JpaRepository不影響save等操作呢,進入JpaRepository這個類,然后發現它也是繼承的其他的類:

public interface JpaRepository extends PagingAndSortingRepository, QueryByExampleExecutor {

他繼承的這個類,繼承的就是CrudRepository:

public interface PagingAndSortingRepository extends CrudRepository {

這也解決了我另一個疑惑,為什么有的類繼承的 PagingAndSortingRepository對save等方法也沒有影響,原來他也是繼承的。

總結

有些東西看起來復雜,寫起來還是挺順手的,對于SQL這個東西,要了解的還是挺多的,畢竟現在用的語句還是查出來的。

總結

以上是生活随笔為你收集整理的jpa原生query_JPA执行原生SQL语句的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。