业务复现

1
2
3
4
5
QueryWrapper<Post> postQueryWrapper = new QueryWrapper<>();
postQueryWrapper.eq("detection_status",DETECTION_SUCCESS)
.eq("has_delete",0)
.eq(!Strings.isBlank(tagId),"tag_id",tagId)//tagId 不为空 更具tagId 查询
.orderByDesc(strategyMap.get(order));

在进行分页查询的时候,此时数据库中的数据是无序的,假设数据库中有三个数据1,3,5

第一次查询的时候可能是 1,3,5 的顺序,此时在第一页取俩条数据是1和3

第二次查询的时候可能是 1,5,3 的顺序,此时在第二页取俩条数据是3

此时导致俩次查询到同一条数据2

第一次问题的解决办法

1
2
3
4
5
6
QueryWrapper<Post> postQueryWrapper = new QueryWrapper<>();
postQueryWrapper.eq("detection_status",DETECTION_SUCCESS)
.eq("has_delete",0)
.eq(!Strings.isBlank(tagId),"tag_id",tagId)//tagId 不为空 更具tagId 查询
.orderByDesc(strategyMap.get(order))
.orderByDesc("post_id");

既然查询的数据是无序的,那我们就让他进行一个排序的操作,那当然不会有重复数据的问题啦qwq

其实会有新的问题!

以1,3,5 举例

我们第一次查询第一页的俩条数据 1,3

此时插入一条数据 2,数据库中的数据为 1,2,3,5

我们在第二页查询俩条数据,返回的数据为3,5

也就是第一次查询的数据3再次被查到了。

第二次解决方法(游标查找)

我们在查询数据的时候,让前端返回一个上一次查询的最大值,以上一个例子举例,第二次查询的时候我们让前端返回第一次查询的最大值,也就是3,那么我们第二次查询的时候就查找比3大的俩条数据就行啦~~

需要注意的是,当我们使用游标分页的方法时,无法直接获取到指定页数,而是必须从前往后逐页遍历。这与 ES 的 scroll 是类似的。