溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

詳解Spring Data JPA如何實現帶條件分頁查詢

發布時間:2020-07-21 16:57:30 來源:億速云 閱讀:565 作者:小豬 欄目:編程語言

小編這次要給大家分享的是詳解Spring Data JPA如何實現帶條件分頁查詢,文章內容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

Spring Data JPA的Specification類, 是按照Eric Evans的《領域驅動設計》書中Specification的概念和語義來定義查詢條件的API。
使用Spring Data JPA, 我們一般將自己的dao接口繼承CrudRepository接口和JpaSpecificationExecutor接口, 由框架生成代理類來完成具體的調用, 而不用自己寫daoImpl實現類, 因為這兩個接口自帶了很多方法, 如果我們寫實現類會發現一上來就需要實現十來個方法, 比較麻煩。

其中CrudRepository接口主要負責增/刪/改的操作, JpaSpecificationExecutor接口主要負責查詢的操作, 另外, 框架還支持在dao接口的方法名上定義一些簡單的語義來進行增刪改查, 底層會對應地做具體實現。

那如何封裝具體的查詢條件呢?

在service層調用dao接口從JpaSpecificationExecutor繼承的抽象查詢方法, 它就會自動讓你準備相關實參, 其中Specification對象就是經常用在條件查詢的方法的一個形參, 也就是說, 封裝查詢條件的過程轉移到service層了。

我們一般以匿名內部類的方式new一個Specification對象, 實現其中的toPredicate方法, 舉個例子,

Specification<Person> specification = new Specification<Person>() {
      @Override
      public Predicate toPredicate(Root<Person> root, CriteriaQuery<&#63;> criteriaQuery, CriteriaBuilder criteriaBuilder) {
      ...
};

其中, Predicate, Root, CriteriaQuery, CriteriaBuilder都是javax.persistence包中的接口, 方法的這3個實參由框架交給我們。

Predicate意思是"描述語", 就是我們封裝完查詢條件后要交給Specification一個清楚的描述, 要怎么組合sql語句去查詢。

Root表示為泛型里的Person對象描述一個根位置, 可以從這個根位置去取該對象的屬性, 以及屬性的屬性, 類似對象導航的意思, 比如要取Person地址屬性的城市, 就可以root.get("address").get("city").as(String.class), 其返回值是一個Expression對象;

CriteriaQuery代表條件查詢,主要提供where、group by、having、order by等。

CriteriaBuilder用于構造篩選條件,主要提供equal、and、or、lt、gt、between、like等, 以及獲得CriteriaQuery、CriteriaUpdate、CriteriaDelete對象。構造每個篩選條件一般需要Expression類型作為實參, 可以通過Root對象調用get()方法得到。如果有多個篩選條件, 調用criteriaBuilder的and、or等方法連接起來, 一般是鏈式調用的形式。

舉個簡單的實際例子:

//帶條件的分頁查詢, 根據person的first_name和last_name進行模糊查詢
//為了直觀, 假設兩個字段都存在且不為空串, 省掉非空判斷和對應的處理
public Page<Person> findSearch(Person person, int page, int size) {
  Specification<Person> specification = new Specification<Person>() {
   @Override
   public Predicate toPredicate(Root<Person> root, CriteriaQuery<&#63;> criteriaQuery, CriteriaBuilder criteriaBuilder) {
      Predicate predicate1 = criteriaBuilder.like(root.get("first_name").as(String.class), "%"+person.getFirstName()+"%");
      Predicate predicate2 = criteriaBuilder.like(root.get("last_name").as(String.class), "%"+person.getLastName()+"%");
        Predicate finalPredicate = criteriaBuilder.and(predicate1, predicate2);
       return finalPredicate;
   }
  };
  PageRequest pageRequest = PageRequest.of(page-1, size);
  return personDao.findAll(specification, pageRequest);
}

當然這都是JPQL的語法了, 很多開發者也經常在dao接口中直接寫SQL語句來讓框架查詢, 使用起來感覺有點類似MyBatis, 會顯得清爽很多, 只需定義一個抽象方法加上對應的注解@Modifying和@Query(value="sql語句", nativeQuery=true)即可, 它還有一個好處, 不用讓封裝查詢條件這種事情跑到service層去。

看完這篇關于詳解Spring Data JPA如何實現帶條件分頁查詢的文章,如果覺得文章內容寫得不錯的話,可以把它分享出去給更多人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女