Spring Page分页查询实现


1. 模拟分页

假分页即全量从数据库读取,再利用前端组件进行分页展示。这么做虽然最简单粗暴,但面对大数据量不仅对数据库压力大,而且前端一次性将大量数据载入内存中会大大降低页面响应速度。

Antd 中的 a-table 默认就是假分页,后端数据一次性加载到前端页面再由前端实现渲染,适合数据量不大的常见,这里就不具体举例了。

2. 分页查询

相应对假分页即真分页,故顾名思义即通过如 MySQLlimit 关键字降低数据库压力,在大数据量时能够有更高的效率但是实现相对更为复杂。

在数据库查询时通过 limit 关键字实现分页查询,不同数据库的关键字不同这里以 MySQL 举例,如下将查询的数据区间为 [2, 5],即第 2 条数据至第 5 条。

select
    id, name, gender, create_time
from sys_user
limit 2, 5;

3. 数据封装

(1) Service

Spring Boot 中自带了 Page 对象提供了数据分页服务,实现分页数据的对象封装。

@Service("sysUserService")
public class SysUserServiceImpl implements SysUserService {
    public Page<SysUser> queryByPage(SysUser sysUser, int offset, int limit) {
        // 构造分页条件
        PageRequest request = PageRequest.of(offset, limit);
        // 分页查询数据
        long total = this.sysUserDao.count(sysUser);
        List<SysUser> data = sysUserDao.queryAllByLimit(sysUser, request)
        // 构造分页对象
        Page<SysUser> pageInfo = new PageImpl<>(data, request, total);
        return pageInfo;
    }
}

@Mapper
public interface SysUserDao {
    List<SysUser> queryAllByLimit(SysUser sysUser, @Param("pageable") Pageable pageable);
}
(2) SQL

SQL 命令中通过 limit 关键字实现分页查询。

<select id="queryAllByLimit" resultMap="SysUserMap">
    select *
    from sys_user
    <where>
        <if test="sysUser.id != null">
            and id = #{id}
        </if>
        <if test="sysUser.username != null and sysUser.username != ''">
            and username = #{username}
        </if>
        <if test="sysUser.password != null and sysUser.password != ''">
            and password = #{password}
        </if>
    </where>
    limit #{pageable.offset}, #{pageable.pageSize}
</select>

4. 前端设计

这里以 Antd 表格为例,在标签内添加 pagination 属性。

<a-table
    :columns="columns"
    :data-source="data"
    :pagination="pagination"
    :bordered="false"
/>

pagination 具体定义参数如下,在 onShowSizeChange()onChange() 事件中调用之前定义的后端分页查询接口即可。

其中 updatePage() 方法即根据前端变更的页数调用后端中定义的分页查询接口。

data() {
    return {
        data: [],
        tableData: [],
        pageRequest: {
            offset: 1,
            limit: 5
        },
        pagination: {
            total: 0, // 总数,必须先有
            defaultCurrent: 1, // 默认当前页数
            defaultPageSize: 5, // 默认当前页显示数据的大小
            showSizeChanger: true,
            showQuickJumper: true,
            pageSizeOptions: ["5", "10", "15", "20"],
            showTotal: (total) => `共 ${total} 条`, // 显示总数
            // 改变每页数量触发
            onShowSizeChange: (current, pageSize) => {
                this.pagination.defaultCurrent = 1
                this.pagination.defaultPageSize = pageSize
                this.updatePage(current, pageSize)
            },
            // 点击页数触发
            onChange: (current, size) => {
                this.pagination.defaultCurrent = current
                this.pagination.defaultPageSize = size
                this.updatePage(current, size)
            }
        }
    }
}

文章作者: 烽火戏诸诸诸侯
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 烽火戏诸诸诸侯 !
  目录