java实现分页数据每页按比率展示不同类型的数据

不知道大家在开发中有没有遇到这种情况,就是要分页返回给前端数据,但是每页展示的数据 类型又是不一样的

 如:电商平台的商品瀑布流,可能会有自营和非自营商品的区别,那么每页展示的数据需要一部分为自营商品,一部分为非自营的商品,那这个时候后端要给的数据就需要动些脑子了,这个需求是小编实实在在遇到的需求,当初为了实现在百度和谷歌找了个遍也没找到相关的思路

 话不多说,上代码,希望有人能用得到


import lombok.Data;

import java.io.Serializable;

/**
 * <p>
 *     说明: 比率分页请求参数
 * </p>
 *
 * @author Z.jc
 * @version 1.0.0
 * @since 2020/8/30
 */
@Data
public class RatioPaginationParam implements Serializable {
    private static final long serialVersionUID = -1496754980781572809L;

    /**
     * 总条数
     */
    private int allCount;

    /**
     * 优先总条数 如自营于非自营商品 自营商品优先/或非自营商品优先,自己理清楚
     */
    private int priorityCount;

    /**
     * 优先数据每页展示长度比率 (重点:优先数据比率)
     */
    private int ratio;

    /**
     * 当前页 用户请求当前页
     */
    private int current;

    /**
     * 每页展示 用户请求每页展示
     */
    private int pageSize;
}
import lombok.Data;

import java.io.Serializable;

/**
 * <p>说明:</p>
 *
 * @author Z.jc
 * @version 1.0.0
 * @since 2020/8/30
 */
@Data
public class RatioPagination implements Serializable {
    private static final long serialVersionUID = 6722234949377171106L;

    /**
     * 优先 limit 开始
     */
    private int priorityLimitStart;
    /**
     * 优先limit 长度
     */
    private int prioritySize;
    /**
     * 非优先limit 开始
     */
    private int nonPriorityLimitStart;
    /**
     * 非优先limit 长度
     */
    private int nonPrioritySize;

    public RatioPagination(int priorityLimitStart,int prioritySize,int nonPriorityLimitStart,int nonPrioritySize){
        this.priorityLimitStart = priorityLimitStart;
        this.prioritySize = prioritySize;
        this.nonPriorityLimitStart = nonPriorityLimitStart;
        this.nonPrioritySize = nonPrioritySize;

    }
}
/**
 * <p>
 *     说明: 商品分组工具类
 * </p>
 *
 * @author Z.jc
 * @version 1.0.0
 * @since 2020/8/30
 */
public class GroupGoodsUtil {

    private GroupGoodsUtil(){}

    /**
     * 数据比对
     * @param num1 对比值1
     * @param num2 对比值2
     * @return 返回结果值 1:num1 gt num2  0:num1 eq num2 -1:num1 lt num2
     */
    public static Integer contrast(int num1,int num2){
        return Integer.compare(num1, num2);
    }


    /**
     * 计算分页参数
     * <p>若使用该方法计算分页参数,请使用limit 查询list 自己封装到pageResult </p>
     * @param param 计算分页参数 请求参数
     * @return 返回比率分页参数
     */
    public static RatioPagination ratioPaginationCalculation(RatioPaginationParam param){
        //优先每页展示率算出当前页展示size
        int priorityPageSize = Math.toIntExact((long)param.getRatio() * param.getPageSize() / 10000);
        //计算优先总页数
        int priorityPageCount = (param.getPriorityCount() + priorityPageSize - 1) / priorityPageSize;
        //计算非优先总条数
        int nonPriorityCount = param.getAllCount() - param.getPriorityCount();
        //计算非优先每页展示
        int nonPriorityPageSize = param.getPageSize() - priorityPageSize;
        //计算非优先总页数
        int nonPriorityPageCount = (nonPriorityCount + nonPriorityPageSize - 1)/nonPriorityPageSize;
        int contrastResult = contrast(priorityPageCount,nonPriorityPageCount);

        int priorityLimitStart = -1;
        int prioritySize = -1;
        int nonPriorityLimitStart = -1;
        int nonPrioritySize = -1;
        switch (contrastResult){
            //优先页小于非优先页
            case -1:
                //当前页小于优先页总页数,可进行正常比率查询
                if (param.getCurrent() < priorityPageCount) {
                    //优先每页长度 * 到上一页页书 = 当前页开始index
                    priorityLimitStart = priorityPageSize * (param.getCurrent() - 1);
                    prioritySize = priorityPageSize;

                    nonPriorityLimitStart = nonPriorityPageSize * (param.getCurrent() -1);
                    nonPrioritySize = nonPriorityPageSize;
                    return new RatioPagination(priorityLimitStart,prioritySize,nonPriorityLimitStart,nonPrioritySize);
                }
                //当前页大于优先页总页数,代表优先数据已全部展示完毕,当前页不考虑比率,全部取非优先数据
                if (param.getCurrent() > priorityPageCount) {
                    //优先页pageSize * 优先页pageCount - 优先页Count = 优先页末页缺失条数
                    int priorityLastPageDefect = priorityPageSize * priorityPageCount - param.getPriorityCount();
                    //优先总页*非优先每页展示量 + 优先页缺失条数 = 优先页结束时非优先已展示数据总量
                    int priorityEndNonPriorityCount = priorityPageCount * nonPriorityPageSize + priorityLastPageDefect;
                    //优先分页结束后到当前页上一页非优先的展示总数
                    int afterEndCount = (param.getCurrent() - 1 - priorityPageCount) * param.getPageSize();
                    nonPriorityLimitStart = priorityEndNonPriorityCount + afterEndCount;
                    nonPrioritySize = param.getPageSize();
                    return new RatioPagination(priorityLimitStart,prioritySize,nonPriorityLimitStart,nonPrioritySize);
                }
                //当前页等于优先页总数 则代表当前页为优先页末页,需要考虑优先数据是否满足比率要求数量,若不满足则用非优先数据补齐
                if (param.getCurrent() == priorityPageCount) {
                    //优先页pageSize * 优先页pageCount - 优先页Count = 优先页末页缺失条数
                    int priorityLastPageDefect = priorityPageSize * priorityPageCount - param.getPriorityCount();
                    priorityLimitStart = priorityPageSize * (param.getCurrent() - 1);
                    prioritySize = priorityPageSize - priorityLastPageDefect;

                    nonPriorityLimitStart = nonPriorityPageSize * (param.getCurrent() -1);
                    nonPrioritySize = nonPriorityPageSize + priorityLastPageDefect;
                    return new RatioPagination(priorityLimitStart,prioritySize,nonPriorityLimitStart,nonPrioritySize);
                }
                throw new CustomException(ResultCode.INVOKE_EXCEPTION,"分页参数计算错误");

            case 0:
                //优先页等于非优先页 正常返回
                priorityLimitStart = priorityPageSize * (param.getCurrent() - 1);
                prioritySize = priorityPageSize;

                nonPriorityLimitStart = nonPriorityPageSize * (param.getCurrent() -1);
                nonPrioritySize = nonPriorityPageSize;
                return new RatioPagination(priorityLimitStart,prioritySize,nonPriorityLimitStart,nonPrioritySize);
            case 1:
                //优先页大于非优先页 则通过非优先页进行分页参数计算
                // 当前页小于非优先页 正常按比率返回
                if (param.getCurrent() < nonPriorityPageCount) {
                    //优先每页长度 * 到上一页页书 = 当前页开始index
                    priorityLimitStart = priorityPageSize * (param.getCurrent() - 1);
                    prioritySize = priorityPageSize;

                    nonPriorityLimitStart = nonPriorityPageSize * (param.getCurrent() -1);
                    nonPrioritySize = nonPriorityPageSize;
                    return new RatioPagination(priorityLimitStart,prioritySize,nonPriorityLimitStart,nonPrioritySize);
                }
                //若当前页大于非优先页 则当前页完全返回优先数据 不考虑比率
                if (param.getCurrent() > nonPriorityPageCount) {
                    //非优先页pageSize * 非优先页pageCount - 非优先页Count = 非优先页末页缺失条数
                    int nonPriorityLastPageDefect = nonPriorityPageSize * nonPriorityPageCount - nonPriorityCount;
                    //非优先总页*优先每页展示量 + 非优先页缺失条数 = 非优先页结束时优先已展示数据总量
                    int nonPriorityEndPriorityCount = nonPriorityPageCount * priorityPageSize + nonPriorityLastPageDefect;
                    //非优先分页结束后到当前页上一页优先的展示总数
                    int afterEndCount = (param.getCurrent() - 1 - nonPriorityPageCount) * param.getPageSize();
                    priorityLimitStart = nonPriorityEndPriorityCount + afterEndCount;
                    prioritySize = param.getPageSize();
                    return new RatioPagination(priorityLimitStart,prioritySize,nonPriorityLimitStart,nonPrioritySize);
                }
                //若当前页等于非优先页,则考虑非优先数据是否满足比率数量,不满足则用优先商品数据补齐
                if (param.getCurrent() == nonPriorityPageCount) {
                    //优先页pageSize * 优先页pageCount - 优先页Count = 优先页末页缺失条数
                    int nonPriorityLastPageDefect = nonPriorityPageSize * nonPriorityPageCount - nonPriorityCount;
                    priorityLimitStart = priorityPageSize * (param.getCurrent() - 1);
                    prioritySize = priorityPageSize + nonPriorityLastPageDefect;

                    nonPriorityLimitStart = nonPriorityPageSize * (param.getCurrent() -1);
                    nonPrioritySize = nonPriorityPageSize - nonPriorityLastPageDefect;
                    return new RatioPagination(priorityLimitStart,prioritySize,nonPriorityLimitStart,nonPrioritySize);
                }
                throw new CustomException(ResultCode.INVOKE_EXCEPTION,"分页参数计算错误");
            default:
                throw new CustomException(ResultCode.INVOKE_EXCEPTION,"分页参数计算错误");
        }
    }

}

以上就是完整的代码了,通过已知参数,计算出当前页两种类型的数据各自的limit参数,然后进行sql limit查询,就可以得到想要的数据啦

此工具类不仅适用于sql查询,同样适用于redis zset查询

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

翟建超

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值