多表分頁查詢,強烈推薦原生sql
一般需要兩個方法,一個查條數,一個查當前頁數據
@Query(value = "" +
"" +
" select " +
"a.id," +
"a.title," +
"a.article_abstract," +
"a.author_id," +
"a.like_count ," +
"a.read_count," +
"a.tags," +
"a.create_time," +
"a.update_time," +
"a.type," +
"a.`status` " +
" from re_article_category rac " +
"" +
" left join " +
" article a " +
"" +
" on a.id=rac.article_id " +
"" +
" where rac.category_id= :catId" +
" and a.status = :status limit :start,:size",nativeQuery = true)
List<Object[]> pageByCatId(@Param("catId") Integer catId,@Param("status")String status,@Param("start")long start, @Param("size")int size);
@Query(value = "select" +
" count(a.id)" +
" from re_article_category rac" +
"" +
" left join " +
" article a" +
"" +
" on a.id=rac.article_id" +
"" +
" where rac.category_id= :catId" +
" and a.status= :status",nativeQuery = true)
Integer countByCat(@Param("catId") Integer catId,@Param("status") String status);
service 層轉換:
//根據分類獲取所有文章
@Override
public Result getPageByCatId(Integer catId, Integer limit, Integer pageNo) {
PageRequest pageRequest = PageRequest.of(pageNo, limit);//藉助計算起始位置
int total=blogDao.countByCat(catId,BLOG_STATUS_NORMAL);// 計算數據總條數
List<Object[]> records=blogDao.pageByCatId(catId,BLOG_STATUS_NORMAL,pageRequest.getOffset(),pageRequest.getPageSize());// 獲取分頁數據
Page<Object[]> page =new Page<>(records,limit,pageNo,total);
page.transferFromSqlList(BlogModel.class);// 轉換分頁數據到具體的java bean
return Result.success(page);
}
}
Page.java(自定義工具)
package com.blog.demo.common.util;
import com.google.common.collect.Lists;
import org.springframework.data.domain.PageImpl;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 與具體ORM實現無關的分頁參數及查詢結果封裝.
*
*
* @param <T> Page中記錄的類型.
*
* @author eagler006 email:[email protected]
* @version 1.2
*/
public class Page<T> {
//-- 分頁參數 --//
protected int pageNo = 1;
protected int pageSize = 15;
protected int first =-1; //此處添加主要是爲了方便分庫分表時計算各表步進取值,當大於0時說明getFirst()函數不從pageNo計算獲得
protected boolean autoCount = true;
protected String sort="id";
protected String dir= "ASC";
//-- 返回結果 --//
protected List result = Lists.newArrayList();
protected long totalCount = -1;
//-- 構造函數 --//
public Page() {
}
public Page(List<Object[]> data,int size,int pageNo,int totalCount){
setPageNo(pageNo);
setPageSize(size);
setTotalCount(totalCount);
setResult(data);
}
public Page(int pageSize) {
this.pageSize = pageSize;
}
public void transferFromSqlList(Class clazz){
List tResult = Lists.newArrayList();
ArrayList<Object> objArr;
for (Object objItem : result){
try {
objArr = new ArrayList<Object>(Arrays.asList((Object[]) objItem));
Constructor<T> constructor = clazz.getDeclaredConstructor(objArr.getClass());
tResult.add(constructor.newInstance(objArr));
} catch (Exception e){
e.printStackTrace();
}
}
this.result = tResult;
}
public void copyPropertiesFromAnother(Page<?> page){
this.pageNo = page.getPageNo();
this.pageSize = page.getPageSize();
this.first = page.getFirst();
this.autoCount = page.isAutoCount();
this.sort = page.getSort();
this.dir = page.getDir();
this.totalCount = page.getTotalCount();
}
//-- 訪問查詢參數函數 --//
/**
* 獲得當前頁的頁號,序號從1開始,默認爲1.
*/
public int getPageNo() {
return pageNo;
}
/**
* 設置當前頁的頁號,序號從1開始,低於1時自動調整爲1.
*/
public void setPageNo(final int pageNo) {
this.pageNo = pageNo;
if (pageNo < 1) {
this.pageNo = 1;
}
}
public Page<T> pageNo(final int thePageNo) {
setPageNo(thePageNo);
return this;
}
/**
* 獲得每頁的記錄數量,默認爲1.
*/
public int getPageSize() {
return pageSize;
}
/**
* 設置每頁的記錄數量,低於1時自動調整爲1.
*/
public void setPageSize(final int pageSize) {
this.pageSize = pageSize;
if (pageSize < 1) {
this.pageSize = 1;
}
}
public Page<T> pageSize(final int thePageSize) {
setPageSize(thePageSize);
return this;
}
/**
* @return the sort
*/
public String getSort() {
return sort;
}
/**
* @param sort the sort to set
*/
public void setSort(String sort) {
this.sort = sort;
}
/**
* @return the dir
*/
public String getDir() {
return dir;
}
/**
* @param dir the dir to set
*/
public void setDir(String dir) {
this.dir = dir;
}
/**
* 根據pageNo和pageSize計算當前頁第一條記錄在總結果集中的位置,序號從1開始.
*/
public int getFirst() {
if(this.first>0)
return first;
return ((pageNo - 1) * pageSize) + 1;
}
/**
* @param first the first to set
*/
public void setFirst(int first) {
this.first = first;
}
/**
* 查詢對象時是否自動另外執行count查詢獲取總記錄數, 默認爲false.
*/
public boolean isAutoCount() {
return autoCount;
}
/**
* 查詢對象時是否自動另外執行count查詢獲取總記錄數.
*/
public void setAutoCount(final boolean autoCount) {
this.autoCount = autoCount;
}
public Page<T> autoCount(final boolean theAutoCount) {
setAutoCount(theAutoCount);
return this;
}
//-- 訪問查詢結果函數 --//
/**
* 取得頁內的記錄列表.
*/
public List getResult() {
return result;
}
/**
* 設置頁內的記錄列表.
*/
public void setResult(final List result) {
this.result = result;
}
/**
* 取得總記錄數, 默認值爲-1.
*/
public long getTotalCount() {
return totalCount;
}
/**
* 設置總記錄數.
*/
public void setTotalCount(final long totalCount) {
this.totalCount = totalCount;
}
/**
* 根據pageSize與totalCount計算總頁數, 默認值爲-1.
*/
public long getTotalPages() {
if (totalCount < 0) {
return -1;
}
long count = totalCount / pageSize;
if (totalCount % pageSize > 0) {
count++;
}
return count;
}
/**
* 是否還有下一頁.
*/
public boolean isHasNext() {
return (pageNo + 1 <= getTotalPages());
}
/**
* 取得下頁的頁號, 序號從1開始.
* 當前頁爲尾頁時仍返回尾頁序號.
*/
public int getNextPage() {
if (isHasNext()) {
return pageNo + 1;
} else {
return pageNo;
}
}
/**
* 是否還有上一頁.
*/
public boolean isHasPre() {
return (pageNo - 1 >= 1);
}
/**
* 取得上頁的頁號, 序號從1開始.
* 當前頁爲首頁時返回首頁序號.
*/
public int getPrePage() {
if (isHasPre()) {
return pageNo - 1;
} else {
return pageNo;
}
}
}
效果:
{
"code": 0,
"msg": "success",
"data": {
"pageNo": 1,
"pageSize": 10,
"first": 1,
"autoCount": true,
"sort": "id",
"dir": "ASC",
"result": [
{
"id": 73,
"title": "標題",
"content": null,
"articleAbstract": "這是簡介,請勿驚訝😨",
"tags": "string",
"type": "1",
"readCount": null,
"likeCount": 1,
"status": "0",
"createTime": "2019-06-06T04:32:01.000+0000",
"updateTime": "2019-06-06T04:32:01.000+0000",
"categoryId": null
},
{
"id": 107,
"title": "正式文章",
"content": null,
"articleAbstract": "發佈一篇文章",
"tags": "string",
"type": "0",
"readCount": 0,
"likeCount": 1,
"status": "0",
"createTime": "2019-06-06T10:32:11.000+0000",
"updateTime": "2019-06-06T10:32:11.000+0000",
"categoryId": null
}
],
"totalCount": 2,
"prePage": 1,
"hasNext": false,
"nextPage": 1,
"hasPre": false,
"totalPages": 1
}
}