Java 分页 核心 组件库

1 概述

分页查询应该是每个程序员必备的技能,因此我特别花了时间,来整理我使用到的分页组件类

2 Java 2种分页方式

2.1 在代码中实现分页(效率很低)

该方式是从数据库中查询出所有的数据,然后在代码层面进行截取。这种方式不推荐,如果数据量太大,非常耗性能

2.2 数据库中进行分页(推荐)

这种主要通过sql进行分页,就是下面这种方式

select * from student limit 10 offset 1;

3 分页核心组件类

①该组件类主要接收前端数据


/**
 * description: 所有有需要的类,继承此类即可
 */
public class ObjectQuery {

    /**
     * 每页显示记录数,默认为每页10条
     */
    private int pageSize = 10;

    /**
     * 当前页页码,默认当前页为1
     */
    private int currentPage = 1;

    /**
     * 开始时间,时间戳  (这里也可以是Date)
     */
    private Long beginTime;

    /**
     * 结束时间,时间戳  (这里也可以是Date)
     */
    private Long endTime;

/**
     * 排序字段,通常这里是和前端约定好的 举例:
     *          0 入库时间倒序
     *          1 入库时间升序
     *          2 id升序
     *          3 id降序
     *
     *  这里也可以采用sql拼接的方式,新增两个属性,放弃sort属性
     *       sortName; 排序字段
     *       sortOrder; 排序方向
     *       然后通过代码,实现sql拼接方式,这种的灵活度最高,但是略微有一点麻烦
     */
    private Integer sort;

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public Long getBeginTime() {
        return beginTime;
    }

    public void setBeginTime(Long beginTime) {
        this.beginTime = beginTime;
    }

    public Long getEndTime() {
        return endTime;
    }

    public void setEndTime(Long endTime) {
        this.endTime = endTime;
    }

    public Integer getSort() {
        return sort;
    }

    public void setSort(Integer sort) {
        this.sort = sort;
    }

    /**
     * 这个方法很有用,平常我们拿到currentPage,pageSize一般在Service层手动
     * 计算offset,这样代码优雅,并且有点麻烦
     * 有了这个方法后,我们可以直接在Mybatis中 使用 #{pageOffset}获取值
     * 例如:LIMIT #{pageSize} offset #{pageOffset} 只要传入的对象继承ObjectQuery
     * Mybatis会通过反射 调用 getPageSize,getPageOffset方法,即使没有属性也可以
     *
     * @return offset
     */
    public int getPageOffset() {
        return (currentPage - 1) * pageSize;
    }
}

②该组件类主要返包装数据,返回给前端


/**
 * description 返回前端界面的分页包装类
 */
public class PageResult<T> implements Serializable, Cloneable {

    /**
     * 每页条数
     */
    private int pageSize;

    /**
     * 总记录数
     */
    private int totalRecords;

    /**
     * 当前页
     */
    private int currentPage;
    /**
     * 总页数
     */
    private int totalPages;

    /**
     * 数据集
     */
    private List<T> items;

    /**
     * 构造分页结果
     * !!!这是创建分页的唯一入口 这是创建分页的唯一入口 这是创建分页的唯一入口
     * !!!没有无参构造器 并且所有方法均为私有,除get方法外
     *
     * @param pageSize    每页条数
     * @param totalRecord 总记录数
     * @param currentPage 当前第几页
     * @param items       数据集合
     */
    public PageResult(int pageSize, int totalRecord, int currentPage, List<T> items) {
        setPageSize(pageSize);
        // 这一步是从数据库中查询出来的总记录数
        this.totalRecords = totalRecord;
        // 有了每一页的页数+总记录数,我们可以计算得到总页数
        this.totalPages = getTotalPages();
        setCurrentPage(currentPage);
        this.items = items;
    }

    private void setPageSize(int pageSize) {
        // 默认10条
        this.pageSize = pageSize > 0 ? pageSize : 10;
    }

    private int getTotalPages() {
        // 12 % 10 = 2;   9 % 10 = 9 这里主要判断总记录数是不是每页条数的整数倍
        int total = this.totalRecords % this.pageSize;
        if (total > 0) {
            // 12 / 10 = 1;    9 / 10 = 0  利用Java整数除法特性,计算得到正确的总记录数
            this.totalPages = this.totalRecords / this.pageSize + 1;
            return totalPages;
        }
        // 总记录数是每页条数的整数倍
        this.totalPages = this.totalRecords / this.pageSize;
        return totalPages;
    }

    private void setCurrentPage(int currentPage) {
        // 如果当前页不是正整数,则赋值为1  !!这里也可以考虑直接抛出异常或者在构造器最开始的时候,就进行参数校验
        if (currentPage == 0 || currentPage < 0) {
            this.currentPage = 1;
            return;
        }
        /*
         * 如果当前页大于总页数,那么就把当前页设置为总页数
         * 不难想到,在这种情况下,是没有任何数据的,及items为空
         *
         * 举例: pageSize         :10
         *       totalRecords     : 13
         *       totalPages       : 2
         *       currentPage      : 3
         *       那么查询就是 (currentPage -1) * pageSize 及从第20条开始查询,总共才13条,自然没有数据
         *       !!但是,一般情况下,currentPage > totalPages是不会发生的,这里有两种方式会导致该情况发生
         *                   ①前端 页面传错参数
         *                   ②有人直接通过API及接口调用,并且传入错误的参数
         *
         */
        if (currentPage > getTotalPages()) {
            this.currentPage = totalPages;
            return;
        }
        this.currentPage = currentPage;
    }

    /*------------------------所有属性的get方法必须存在,反射会用到-----------------------*/

    public List<T> getItems() {
        return items;
    }

    public int getPageSize() {
        return this.pageSize > 0 ? this.pageSize : 10;
    }

    public int getTotalRecords() {
        return this.totalRecords;
    }

    public int getCurrentPage() {
        return this.currentPage;
    }
}
请尊重作者劳动成果,转载请注明出处。以上内容若有侵权,请联系作者,立即删除

猜你喜欢

转载自www.cnblogs.com/AdaiCoffee/p/11285596.html