Java專案開發中實現分頁的三種方式一篇包會

福隆苑居士發表於2022-02-05

前言

  Java專案開發中經常要用到分頁功能,現在普遍使用SpringBoot進行快速開發,而資料層主要整合SpringDataJPA和MyBatis兩種框架,這兩種框架都提供了相應的分頁工具,使用方式也很簡單,可本人在工作中除此以外還用到第三種更方便靈活的分頁方式,在這裡一同分享給大家。



使用

主要分為SpringDataJPA分頁、MyBatis分頁、Hutools工具類分頁幾個部分


1、SpringDataJPA分頁

1)、引入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

2)、Service中編寫分頁服務

  SpringDataJPA分頁就是定義Pageable物件來處理分頁,其中PageRequest來定義分頁引數,Page物件來接手查詢結果進行分頁包裝,包裝後的結果pageResult可以得到總記錄數、總頁數、分頁列表等資料結果。

/**
 * 根據doctorId查詢全部關注列表【分頁】
 *
 * @param doctorId 醫生id
 * @return 結果集
 */
public Map<String, Object> findAllListByDoctorId(Long doctorId, Integer pageIndex, Integer pageSize) {
	Pageable pageable = PageRequest.of(pageIndex - 1, pageSize); // 分頁
	Page<Follow> pageResult = followRepository.findByDoctorIdOrderByCreatedAtDesc(doctorId, pageable);
	List<FollowDTO> dtoList = followMapper.toDto(pageResult.getContent());
	if (!CollectionUtils.isEmpty(dtoList)) {
		// 處理業務邏輯....
	}
	// 封裝分頁結果
	Map<String, Object> map = new HashMap<>();
	map.put("pageIndex", pageIndex.toString()); // 當前頁
	map.put("pageSize", pageSize.toString()); // 每頁條數
	map.put("total", Long.toString(pageResult.getTotalElements())); // 總記錄數
	map.put("pages", Integer.toString(pageResult.getTotalPages())); // 總頁數
	map.put("list", dtoList); // 資料列表
	return map;
}

3)、Repository中處理分頁

  這裡就是繼承JpaRepository物件,然後傳入service中定義好的pageable物件,並且返回Page包裝的結果即可。

import com.patient.domain.Follow;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

@Repository
public interface FollowRepository extends JpaRepository<Follow, Long> {

    Page<Follow> findByDoctorIdOrderByCreatedAtDesc(Long doctorId, Pageable pageable);
}

2、MyBatis分頁

1)、引入PageHelper依賴

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>

2)、使用PageHelper實現分頁

/**
 * 查詢推廣人員列表,分頁。
 * @return 封裝的分頁結果物件
 */
public PageResult findPromotePersonList(String hospitalCode,PromotePersonReq promotePersonReq) {
	Integer pageIndex = promotePersonReq.getPageIndex();
	Integer pageSize = promotePersonReq.getPageSize();
	PageHelper.startPage(pageIndex, pageSize); // 每頁的大小為pageSize,查詢第page頁的結果
	List<PromotePerson> list = promotePersonMapper.selectAll();
	PageInfo<PromotePerson> pageInfo = new PageInfo<>(list);
	PageHelper.clearPage();
	// 返回分頁結果
	PageResult pageResult = new PageResult();
	pageResult.setPageIndex(pageIndex);
	pageResult.setPageSize(pageSize);
	pageResult.setPages(pageInfo.getPages());
	pageResult.setTotal((int) pageInfo.getTotal());
	pageResult.setList(list);
	return pageResult;
}

3、Hutools工具類分頁

1)、引入依賴

  這裡是可以單獨引入hutools部分工具類的,具體參考官網文件,我平時寫專案一定會使用這個工具,所以直接引入了所有。

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.1.2</version>
</dependency>

2)、分頁實現

  一般就用到兩個工具類,一是PageUtil.totalPage(總記錄數, 每頁記錄數)來計算總頁數,二是CollUtil.page(索引, 每頁記錄數, 資料列表)來返回指定分頁結果,注意這裡的索引是從1開始的,和SpringDataJPA分頁索引從0開始有區別。

/**
 * 我的訂單-待支付[分頁]
 *
 * @param openid 使用者唯一標識
 * @return 結果集
 */
public Map<String, Object> findMyOrderNotPay(String openid, Integer pageIndex, Integer pageSize) {
	Map<String, Object> map = new HashMap<>();
	// 查詢
	List<ConsultOrder> orderList = consultOrderRepository.findMyOrderNotPay(openid);
	if (CollectionUtils.isEmpty(orderList)) {
            map.put("pageIndex", pageIndex.toString()); // 當前頁
            map.put("pageSize", pageSize.toString()); // 每頁條數
            map.put("total", "0"); // 總記錄數
            map.put("pages", "0"); // 總頁數
            map.put("list", new ArrayList<>()); // 資料列表
            return map;
	}
	List<OrderVO> pageList = new ArrayList<>();
	int totalSize = 0;
	int totalPage = 0;
	// 計算總頁數
	totalSize = orderList.size();
        totalPage = PageUtil.totalPage(totalSize, pageSize);
	// 分頁,索引小於等於總頁數,才返回列表.
	if (pageIndex <= totalPage) {
            // 分頁
            pageList = CollUtil.page(pageIndex, pageSize, orderVOList);
	}
	// 返回結果
	map.put("pageIndex", Integer.toString(pageIndex)); // 當前頁
	map.put("pageSize", Integer.toString(pageSize)); // 每頁條數
	map.put("total", Integer.toString(totalSize)); // 總記錄數
	map.put("pages", Integer.toString(totalPage)); // 總頁數
	map.put("list", pageList); // 資料列表
	return map;
}



總結

  1)、注意 :為了方便演示程式碼中直接用了Map物件來包裝返回分頁結果,在實際專案中,切記一定要自己定義實體物件作為返回結果,因為Map物件返回的結果如果是動態且資料量較大的列表,是存在造成記憶體洩露風險的,舉個例子,比如返回10條問診的分頁記錄時,其中聊天內容這個屬性包含大量聊天資料,因為你無法確定對話的兩個人到底聊了多少,可它確實作為一個屬性包含在分頁記錄中;


  2)、SpringDataJPA分頁,就是使用自帶的Pageable物件來處理,需要注意的是分頁索引從0開始,傳錯了會造成分頁結果錯亂或重複的現象;


  3)、Mybatis分頁,就是藉助PageHelper工具來實現,PageHelper.startPage和PageHelper.clearPage中間是需要分頁的業務查詢程式碼,可以通過PageInfo物件包裝,獲取其中需要的分頁引數返回給前端展示;


  4)、Hutools分頁,就是引入hutools工具類,使用其中的PageUtil和CollUtil工具類來實現,這種方式我個人比較喜歡,因為在較複雜的查詢業務中,前兩種實現起來很費勁還容易寫錯,不僅可能牽扯到多個類及方法,寫完後過段時間也不容易閱讀。而Hutools分頁就類似於很早以前的分頁方式,我把它理解為綠色簡易版JSP分頁,只需在服務層使用一個工具類分頁即可,既靈活又便於閱讀,簡直是分頁的神器。



  本人文章從來都是純手打,且都來自實際工作中的經驗及分享,如果覺得有一滴滴幫助,就點個推薦吧!(o..o)~


相關文章