数据库和外置缓存一起分页

一. 前言

前段时间,小熙要在数据库外做二级缓存并和数据库一起提供对外服务。其中两者一起的分页小熙提取出来了,做下记录。

二. 工具类以及部分代码:

  1. 封装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;
    }
    
  2. 简易分页接收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;
    
        }
    
  3. 处理核心代码(其他无关地方不方便展示):

        /**
         * 根据缓存设置分页参数(共有三种情况,分类返回)
         * @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);
        }
    
  4. 缓存分页工具:

      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 + "]";
              }
    
        }
    
    

三. 示例:

  1. 获取处理情况返回类
    PaginationParamDTO paginationParamDTO = PageVoUtil.setPaginationParam(pageVoDTO, cacheVOList.size()); 
    
  2. 根据情况分类查询,
    (1)如果缓存完全可用,则使用缓存分页工具查询
    (2)如果完全是数据库中的,则按照处理情况返回类中的开始索引和分页长度进行分页(mysql中limit,Oracle中伪列)
    (3)如果是混合的,则缓存中加上数据库的分页的(就是以上两种情况组合,对应数值在返回类中都有标注)

四. 后语

如果有比小熙更好的方法,也请分享下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值