1. 模拟分页
假分页即全量从数据库读取,再利用前端组件进行分页展示。这么做虽然最简单粗暴,但面对大数据量不仅对数据库压力大,而且前端一次性将大量数据载入内存中会大大降低页面响应速度。
如 Antd
中的 a-table
默认就是假分页,后端数据一次性加载到前端页面再由前端实现渲染,适合数据量不大的常见,这里就不具体举例了。
2. 分页查询
相应对假分页即真分页,故顾名思义即通过如 MySQL
中 limit
关键字降低数据库压力,在大数据量时能够有更高的效率但是实现相对更为复杂。
在数据库查询时通过 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)
}
}
}
}