在實際項目中對Spring Data的各類使用至關多,簡單的增刪改查Spring Data提供了現成的方法,一些複雜的,咱們能夠在接口方法寫And,Not等關鍵字來搞定,想寫原生SQL,CQL(Neo4j),Query DSL (Elasticsearch)的,直接使用@Query(「......」)註解搞定,真的是方便到不行!html
本篇博客不打算講Spring Data如何使用,不一樣的模塊(JPA,Neo4j....)使用也略不相同,但Spring Data的排序Sort
和分頁Pageable
接口都是差很少的,因此帶你們搞明白搞明白Spring Data的排序和分頁是如何使用的。redis
Spring Data的任務是爲數據訪問提供一個熟悉的、一致的、基於Spring的編程模型,同時仍然保留底層數據存儲的特殊特性。spring
Spring Data 項目的目的是爲了簡化構建基於 Spring 框架應用的數據訪問計數,包括非關係數據庫、Map-Reduce 框架、雲數據服務等等;另外也包含對關係數據庫的訪問支持。sql
SpringData讓數據訪問變得更加方便。mongodb
Spring Data數據庫
經過一行代碼就能夠快速使用:編程
Sort sort = new Sort(Sort.Direction.DESC, "id");
在Sort類中定義了一個枚舉類型Direction
,該枚舉類型聲明瞭兩個常量ASC
,DESC
定義方向。該構造方法的第一個參數指明方向降序(DESC
)或升序(ASC),第二個參數指明以id
列的值爲準進行排序。後端
你也能夠建立一個多屬性的Sort實例。api
Sort(Sort.Direction direction, List<String> properties)
你也能夠只傳入屬性而不聲明方向:微信
Sort(String... properties)
不過官方已經棄用該方法,推薦使用
public static Sort by(String... properties)
當你不聲明方向時,默認方向爲升序。
public static final Direction DEFAULT_DIRECTION = Direction.ASC;
Sort的一些方法
修飾符和類型 | 方法和描述 |
---|---|
Sort |
and(Sort sort) 返回由當前排序的排序順序與給定的排序順序組成的新排序。 |
Sort |
ascending() 返回具備當前設置但升序方向的新排序。 |
static Sort |
by(List<Sort.Order> orders) 爲給定的 Sort.Order 建立一個新的排序。 |
static Sort |
by(Sort.Direction direction, String... properties) 建立一個新的排序。 |
static Sort |
by(Sort.Order... orders) Creates a new Sort for the given Sort.Order s. |
static Sort |
by(String... properties) Creates a new Sort for the given properties. |
Sort |
descending() 返回具備當前設置但順序相反的新排序。 |
boolean |
equals(Object obj) |
Sort.Order |
getOrderFor(String property) 根據property獲取Order |
boolean |
isSorted() |
boolean |
isUnsorted() |
Iterator<Sort.Order> |
iterator() |
static Sort |
unsorted() 返回一個根本沒有排序設置的排序實例。 |
Sort.Order
是Sort的
一個靜態內部類,官方說明是:PropertyPath實現了排序的配對。方向和屬性。它用於提供排序的輸入 。
簡單來說,你能夠定義一個Order,在須要時傳入order構建Sord實例。
Order(Sort.Direction direction, String property)
更獨特的使用是加入本身的空處理提示的枚舉:
Order(Sort.Direction direction, String property, Sort.NullHandling nullHandlingHint)
Sort.NullHandling
是可用於排序表達式的空處理提示的枚舉。對使用的數據存儲的一種提示,用於在非空條目以後對具備空值的條目進行排序。
在須要Sort時,可經過Order建立:
Sort(Sort.Order... orders)
Sort.Order的一些方法
修飾符和類型 | 方法和描述 |
---|---|
static Sort.Order |
asc(String property) 建立升序的Order實例 |
static Sort.Order |
by(String property) 建立默認方向的Order實例 |
static Sort.Order |
desc(String property) 建立降序的Order實例 |
Sort.Direction |
getDirection() |
Sort.NullHandling |
getNullHandling() |
String |
getProperty() |
Sort.Order |
ignoreCase() 開啓不分大小寫排序 |
boolean |
isAscending() 返回此屬性的排序是否要升序。 |
boolean |
isDescending() 返回此屬性的排序是否應該降序。 |
boolean |
isIgnoreCase() 返回該排序是否區分大小寫。 |
Sort.Order |
nullsFirst() 返回 Sort.Order 使用 Sort.NullHandling.NULLS_FIRST 做爲空處理提示。First:第一個 |
Sort.Order |
nullsLast() 返回 Sort.Order 使用Sort.NullHandling.NULLS_LAST 做爲空處理提示。Last:最後一個 |
Sort.Order |
nullsNative() 返回 Sort.Order 使用Sort.NullHandling.NATIVE 做爲空處理提示。NATIVE:原生的 |
Sort.Order |
with(Sort.Direction direction) 建立Order實例. |
Sort.Order |
with(Sort.NullHandling nullHandling) 建立Order實例. |
Sort |
withProperties(String... properties) 建立Order實例. |
Sort.Order |
withProperty(String property) 建立Order實例. |
若是你還想全面瞭解它的使用,推薦閱讀官方英文文檔:https://docs.spring.io/spring-data/data-commons/docs/current/api/org/springframework/data/domain/Sort.html
Pageable只是 Spring Data 提供的分頁信息的抽象接口。
實現類:
AbstractPageRequest:抽象類。供PageRequest
和QPageRequest
繼承。
PageRequest: 基本的可頁面化Java Bean實現。
QPageRequest:基本的Java Bean實現,能夠支持QueryDSL。
分頁功能也只須要一行代碼:
Pageable pageable = new PageRequest(int page, int size, Sort sort);
page
- 從零開始的索引頁
size
- 要返回的頁面的大小
sort
- 排序
你也能夠建立沒有排序的分頁
PageRequest(int page, int size)
更方便的是能夠一行代碼建立有排序方向和屬性的分頁
PageRequest(int page, int size, Sort.Direction direction, String... properties)
若是你使用的是2.0之後的版本,官方已經棄用以上構造方法的形式,推薦使用靜態方法:
修飾符和類型 | 方法和描述 |
---|---|
static PageRequest |
of(int page, int size) |
static PageRequest |
of(int page, int size, Sort.Direction direction, String... properties) |
static PageRequest |
of(int page, int size, Sort sort) |
好比咱們想遍歷整個數據表,就可使用分頁遍歷,這樣不至於一次把數據所有加載到內存。
修飾符和類型 | 方法和描述 |
---|---|
Pageable |
first() 請求第一頁。 |
Sort |
getSort() 返回排序參數。 |
Pageable |
next() 請求下一個頁面。 |
PageRequest |
previous() 請求前一頁。 |
注意:在使用next()
方法時,不要把pageable.next()
直接做爲參數傳入方法,如repository.findAll(page.next())
這樣的寫法會致使死循環。查看next()方法的源碼發現這個方法只是幫咱們new了一個新的Pageable
對象,原來的pageable
仍是沒啥變化。一直next()下去也只是在原地踏步。
public Pageable next() { return new PageRequest(getPageNumber() + 1, getPageSize(), getSort()); }
正確的寫法:
repository.findAll(pageable = pageable.next());
Spring Data Jpa除了會經過命名規範幫助咱們擴展Sql語句外,還會幫助咱們處理類型爲Pageable
的參數,將pageable
參數轉換成爲sql語句中的條件,同時,還會幫助咱們處理類型爲Page
的返回值,當發現返回值類型爲Page
,Spring Data Jpa將會把數據的總體信息、當前數據的信息,分頁的信息都放入到返回值中。這樣,咱們就可以方便的進行個性化的分頁查詢。
public interface UserRepository extends JpaRepository<User,Long> { @Override Page<Medical> findAll(Pageable pageable); }
若是你想用@Query寫原生查詢語句並實現分頁:
Spring Data JPA目前不支持原生查詢的動態排序,由於它必須操做聲明的實際查詢,這對於原生SQL是沒法可靠地作到的。可是,您能夠經過本身指定count查詢來使用原生查詢進行分頁,以下面的示例所示:
public interface UserRepository extends JpaRepository<User, Long> { @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1", countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1", nativeQuery = true) Page<User> findByLastname(String lastname, Pageable pageable); }
分頁查詢:
Page<Book> sampleEntities = userRepository.findAll(pageable);
接口Page
繼承了接口Slice
,話很少說,直接上乾貨!
總頁數
int getTotalPages()
元素的總數
long getTotalElements()
返回當前頁的索引(是第幾頁)
int getNumber()
返回做爲List
的頁面內容
List<T> getContent()
返回當前在這個頁上的元素的數量
int getNumberOfElements()
返回用於請求當前頁的Pageable
default Pageable getPageable()
返回頁的大小。
int getSize()
返回頁的排序參數。
Sort getSort()
頁面是否有內容。
boolean hasContent()
是否有下一頁。
boolean hasNext()
是否有上一頁
boolean hasPrevious()
當前頁是不是第一個
boolean isFirst()
當前頁是不是最後一個
boolean isLast()
下一頁的Pageable
Pageable nextPageable()
上一頁的Pageable
Pageable previousPageable()
關於Spring Data的排序與分頁就到這裏,記得點贊哦~~~
本文已受權微信公衆號「後端技術精選」獨家發佈