以RuoYi为例分析数据分页
在很多网站都有进行数据分页,那么大家一定有疑问为什么要进行数据分页,数据分页又是怎么实现的?本博客专门以RuoYi为例解释上面的问题
在很多网站都有进行数据分页,那么大家一定有疑问为什么要进行数据分页,数据分页又是怎么实现的?
目录
1.数据分页的必要性
-
前端性能和用户体验:
- 减少加载时间:如果一次性加载所有数据,可能导致长时间的加载等待。分页可以减少单次加载的数据量,从而加快页面响应时间。
- 提升用户体验:分页使得用户可以更方便地浏览和定位数据,避免了滚动条过长导致的操作不便。
- 减轻浏览器负担:大量数据同时渲染可能导致浏览器卡顿或崩溃,分页可以有效减轻浏览器的渲染负担。
-
后端性能和资源管理:
- 减轻服务器负担:一次性处理和返回大量数据会对服务器造成很大压力,分页可以显著减轻服务器的处理负担。
- 优化数据库查询:分页可以减少数据库的查询负载,特别是对于大型数据库,这可以大幅提高查询效率。
- 节省网络资源:传输大量数据会消耗大量网络带宽。通过分页,每次只传输需要的数据量,可以有效节省带宽资源。
-
数据管理和安全:
- 更好的数据管理:对于后台管理系统,分页可以帮助管理员更有效地管理数据,快速定位和处理数据。
- 安全考虑:在一些应用中,为了数据安全,限制一次可以访问的数据量是非常重要的。
2.数据分页的实现
2.1实例分析
首先我们拉起RuoYi找到有数据分页功能的页面,在这里我以日志管理的登陆日志功能为例,因为数据条数比较多,便于我们分析。
进入系统管理 ——日志管理——登陆日志
2.2源码分析
2.2.1前端

pageNum 表示当前的页码。这里初始化为 1,意味着默认情况下加载第一页的数据。这是分页功能中的一个常见参数。
pageSize 表示每页显示的数据条数。这里设置为 10,意味着每页将显示 10 条数据。这个参数用于控制分页组件每页显示数据的数量。



用开发者工具查看前端访问后端的情况

.then(response => {...}):
- 当
list函数的异步操作完成后,.then方法会被调用。 response是从服务器返回的数据。

更新组件状态:
this.list = response.rows;:将返回的数据中的rows属性赋值给组件的list属性。this.total = response.total;:将返回的数据中的total属性赋值给组件的total属性。total表示数据的总数。
2.2.2后端

2.2.2.1 startPage()

总结来说,startPage() 在 BaseController 中作为一个方便子类控制器调用的方法被定义。SysLogininforController 作为 BaseController 的子类,在处理请求时调用了这个方法来设置分页。而 BaseController 的 startPage() 方法内部调用了 PageUtils.startPage(),后者负责实际的分页逻辑处理。
2.2.2.2 getDataTable(list)

getDataTable 方法是一个通用方法,用于将查询到的列表数据和分页信息封装成一个标准化的响应格式。
在这里就出现了一个问题:我们前面看到total 值大于list 长度,那如何通过list 做到的?
答案是通过new PageInfo(list).getTotal();

这里对于强制类型转化然后调用不太理解的可以先跳到3.强制转化的简单示例
2.2.2.3分页实现原理分析

那么我们来分析打印的log
SQL 被MyBatis 拦截改变了,selectLogininfirList 函数对应两句SQL:
一句查询表的总行数[count(0)]
一句对查询数据做了行数输出限制[LIMIT 10]
对应前端参数pageNum=1&pageSize=10 count(0):
表数据的总行数 LIMIT 有两种形式:
LIMIT num:数据的前num 个
LIMIT offset,num:从offset 偏移位置开始的num 个数据
MyBatis 通过startPage 中的函数PageHelper.startPage 做到了对SQL 语句的修改
MyBatis 通过修改SQL 语句,多请求了一句SQL 语句:SELECT count(0) FROM sys_logininfor 返回了总行数给到Page 对象的total 成员。然后通过子类Page 强转父类List 对象,访问其成员total 值,赋值给PageInfo 父类成员total,即this.total = ((Page)list).getTotal();
2.2.2.3分析LIMIT后面值的含义

LIMIT 子句的参数为 10(Long), 10(Integer)。这里,第一个参数 10 表示查询结果的起始位置(偏移量),第二个参数 10 表示查询结果的最大行数(数量)。
由于 SQL 分页是基于 0 开始的,pageNum=2 和 pageSize=10 意味着要查询第二页的数据,每页有 10 条记录。因此,查询的起始位置是 10(第二页的起始索引是 1 * pageSize),数量仍然是 10。
这个 SQL 查询是为了获取第二页的数据,每页显示 10 条记录。由于分页索引从 0 开始,所以第二页的数据实际上是从第 11 条记录开始的,一直到第 20 条记录。
通过这种方式,后端服务能够根据前端请求的页码和页面大小,有效地从数据库中检索出所需的数据范围,以实现分页功能。
3.强制转化的简单示例
3.1自定义一个类MyPage
MyPage继承List,成员含有公有成员total

3.2定义函数selectTotalList
返回类型List<>。函数功能为创建一个MyPage对象,设置成员total 为100,函数返回MyPage 对象

3.3调用 selectTotalList
从返回的List 对象中输出total 的值

输出结果:

更多推荐




所有评论(0)