一. 前言
前段时间,小熙要在数据库外做二级缓存并和数据库一起提供对外服务。其中两者一起的分页小熙提取出来了,做下记录。
二. 工具类以及部分代码:
-
封装DTO类
import lombok.Data; import lombok.experimental.Accessors; /** * @author chengxi * @date 2020/9/11 15:42 */ @Data @Accessors(chain = true) public class PaginationParamDTO { /** * 是否需要在数据库中分页 */ private Boolean isPagination; /** * 是否是混合数据(缓存和数据库中都有数据) */ private Boolean isMixData; /** * limit 的开始分页索引 */ private Integer startIndex; /** * limit 的分页长度 */ private Integer pageSize; /** * 缓存取值的数量(一般倒叙获取), 只有 isMixData 为 true 的时候才有。全部从缓存中取值的时候,不需要获取这个值了(其实这个时候等于pageSize)。 */ private Integer cacheValueNumber; }
-
简易分页接收DOT
import lombok.Data; import lombok.experimental.Accessors; import java.io.Serializable; /** * @author chengxi * @date 2020/7/28 10:09 */ @Data @Accessors(chain = true) public class PageVoDTO implements Serializable { private static final long serialVersionUID = -700369052417113651L; /** * 当前页数,默认为1 */ private Integer currentPage = 1; /** * 页面展示数目,默认为10 */ private Integer pageSize = 10; }
-
处理核心代码(其他无关地方不方便展示):
/** * 根据缓存设置分页参数(共有三种情况,分类返回) * @param pageVoDTO * @param listNumber 缓存数据的长度 * @return 如果返回false,表示不需要在数据库中分页,直接从缓存中分页即可 */ public static PaginationParamDTO setPaginationParam(PageVoDTO pageVoDTO, Integer listNumber){ PaginationParamDTO paginationParamDTO = new PaginationParamDTO(); int totalNumber = pageVoDTO.getCurrentPage() * pageVoDTO.getPageSize(); if (listNumber >= totalNumber) { return paginationParamDTO.setIsPagination(false).setIsMixData(false); } int startPaginationNumber = 0; int calcPageSize = pageVoDTO.getPageSize(); if (listNumber > (totalNumber - pageVoDTO.getPageSize())) { calcPageSize = totalNumber - listNumber; return paginationParamDTO.setIsPagination(true).setIsMixData(true).setStartIndex(startPaginationNumber).setPageSize(calcPageSize).setCacheValueNumber(pageVoDTO.getPageSize() - calcPageSize); } startPaginationNumber = totalNumber - calcPageSize - listNumber; return paginationParamDTO.setIsPagination(true).setIsMixData(false).setStartIndex(startPaginationNumber).setPageSize(calcPageSize); }
-
缓存分页工具:
import lombok.Data; import java.util.List; /** * 程熙cjp:https://blog.csdn.net/weixin_41133233 * 分页工具 * * @author chengxi * @date 2020/9/11 15:12 */ @Data public class PaginationUtil<T> { private Integer pageSize; private Integer totalRecord; private Integer totalPage; private Integer currentPage; private List<T> list; public PaginationUtil(Integer pageNo, Integer pageSize, List<T> sourceList){ if(sourceList.size()==0){ return; } //总记录数 this.totalRecord = sourceList.size(); //每页显示多少条数据 this.pageSize = pageSize; //总页数 this.totalPage = this.totalRecord % this.pageSize == 0?this.totalRecord/this.pageSize:this.totalRecord/this.pageSize+1; //当前第几页 this.currentPage = this.totalPage < pageNo ? this.totalPage:pageNo; //起始索引 Integer fromIndex = this.pageSize * (this.currentPage - 1); //结束索引 Integer endIndex = this.pageSize * this.currentPage >this.totalRecord ? this.totalRecord:this.pageSize * this.currentPage; this.list = sourceList.subList(fromIndex, endIndex); } @Override public String toString() { return "Pager [pageSize=" + pageSize + ", totalRecord=" + totalRecord + ", totalPage=" + totalPage + ", currentPage=" + currentPage + ", list=" + list + "]"; } }
三. 示例:
- 获取处理情况返回类
PaginationParamDTO paginationParamDTO = PageVoUtil.setPaginationParam(pageVoDTO, cacheVOList.size());
- 根据情况分类查询,
(1)如果缓存完全可用,则使用缓存分页工具查询
(2)如果完全是数据库中的,则按照处理情况返回类中的开始索引和分页长度进行分页(mysql中limit,Oracle中伪列)
(3)如果是混合的,则缓存中加上数据库的分页的(就是以上两种情况组合,对应数值在返回类中都有标注)
四. 后语
如果有比小熙更好的方法,也请分享下。