一、问题描述
假设有一组数据量为20的数据,其中满足A条件的数据只有1条。
再假设,分页限制为:每页5条数据。
此时,若显示完整数据有4页,若应用A条件则数据只能显示1页。
一般情况下,前端会限制不让用户在应用A条件后,翻到第二页(干脆不给页面跳转的按钮)。因为没有意义,第二页的数据是空的。
但是,实践中,会出现这种情况,使得用户既能应用A条件,又能翻到第二乃至其他页。以至于用户会看到一个空白的列表页面。
如下图所示:
二、问题产生原因
对于前端:
用户输入查询条件后,不点击“查询”按钮应用查询条件向后端发起请求,此时前端不知道符合查询条件的数据数量,所以不会对可选页码进行限制。
于是直接点击页号,使得页码变化,触发查询。
由于查询表单的数据已经变化,发向后端的请求里,直接就附带了查询条件+新页号的数据。
对于后端:
满足查询条件的数据量不够,不满足新页号那么多页的数据,所以直接返回了空数组。
所以导致最终列表显示为空。
其实,本质上就是分页查询的页号溢出问题。
三、解决办法
理论上应该有三种思路:
前端做判定,改变查询条件后,若不点击一次查询按钮,直接点击页号,那么就忽略变化的内容。其实就是尝试加更多的精细限制,去避免用户试图用溢出的页号进行查询。(未试过,不知思路是否可行)
后端每次做分页查询时,若发现数据不够请求的页号,则自动返回最后一页的分页数据。(未看到怎么支持的示例,或许需要自写Mybatis的拦截器插件?)
后端每次做分页查询时,若发现数据不够请求的页号,则自动返回第一页的分页数据。(最容易做到,因为MybatisPlus已经提供了相应的功能开关)
本文介绍的便是第3点的实现:
本文基于MybatisPlus版本:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
①后端新增MybatisPlus配置类
重点就是 paginationInnerInterceptor.setOverflow(true); 这里要设置为true
参考官网文档链接:《属性介绍》
/**
* MyBatisPlus配置
*/
@Configuration
public class MybatisPlusConfig {
/**
* 配置插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
// 核心插件
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件(如果配置多个插件,切记分页最后添加)
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL); // dbType(数据库类型)
paginationInnerInterceptor.setOverflow(true); // 默认值:false。溢出总页数后是否进行处理。
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
}
②其他的照常,都不用改,直接解决本文描述的问题
此时,当照着问题描述那样操作,点击页码后,会最终页面会直接回到第一页。
特别注意:
前端在获取到后端返回的分页数据时,一定要同步“当前页”字段值。
MybatisPlus的分页信息类
因为前端发送了一个指定页码数据请求,当前页=“frontEndCurrPage”。
后端有两种应答可能:
因为数据量够,所以按照前端指定的页码返回数据,当前页=“frontEndCurrPage”。
因为数据量不够,页码溢出,返回的时候直接是返回第一页数据,当前页=“1”。