RealmResults按最新日期排序及分页查询实现方案咨询
解决Realm分页查询(保留between方法)的问题
我来帮你梳理下这个问题哈,你现在的核心问题是想用between("id")实现分页,但当前写法有两个关键问题:一是排序字段写错了(你的实体类里没有date字段,应该用dateTime),二是直接用id的范围分页,没法保证和按日期排序的结果匹配——毕竟如果id不是严格按交易时间自增生成的,就会拿到不符合预期的分页数据。
下面是符合你需求的改写方案,既保留between方法,又能实现按最新日期排序的分页逻辑:
1. 先修正排序逻辑,确保按日期倒序生效
首先把排序字段改成实体里的dateTime,这是基础:
// 先拿到所有按日期倒序排序的交易数据 RealmResults<Transactions> sortedAllTransactions = realm.where(Transactions.class) .sort("dateTime", Sort.DESCENDING) .findAll();
2. 首次获取最后20条数据(最早的20笔交易)
这里的“最后20条”是指按日期倒序后的末尾20条(也就是最早发生的交易)。我们先拿到总数据量,计算出这20条的位置,再提取它们的id范围,最后用between查询:
int pageSize = 20; int totalCount = sortedAllTransactions.size(); // 计算首次分页的起始索引,避免数据不足20条时索引越界 int startIndex = Math.max(totalCount - pageSize, 0); // 获取这20条数据的最小和最大id,作为between的参数 long firstPageMinId = sortedAllTransactions.get(startIndex).getId(); long firstPageMaxId = sortedAllTransactions.get(totalCount - 1).getId(); // 用between查询首次分页数据,同时保留日期排序 RealmResults<Transactions> firstPage = realm.where(Transactions.class) .sort("dateTime", Sort.DESCENDING) .between("id", firstPageMinId, firstPageMaxId) .findAll();
3. 后续分页获取更早的20条数据
每次加载下一页时,我们需要基于上一页的第一条数据(也就是上一页里最早的交易)的日期,筛选出比它更早的交易,再提取对应id范围用between查询:
// 假设上一页的第一条数据是prevPageFirstItem(上一页里最早的交易) Transactions prevPageFirstItem = firstPage.get(0); // 先查询所有比上一页最早交易还要早的记录,按日期倒序排序 RealmResults<Transactions> earlierTransactions = realm.where(Transactions.class) .lessThan("dateTime", prevPageFirstItem.getDateTime()) .sort("dateTime", Sort.DESCENDING) .findAll(); int earlierCount = earlierTransactions.size(); if (earlierCount == 0) { // 没有更多数据了,直接返回 return; } // 计算当前分页的起始索引 int currentStartIndex = Math.max(earlierCount - pageSize, 0); // 提取当前分页的id范围 long currentPageMinId = earlierTransactions.get(currentStartIndex).getId(); long currentPageMaxId = earlierTransactions.get(earlierCount - 1).getId(); // 用between获取当前页数据 RealmResults<Transactions> nextPage = realm.where(Transactions.class) .sort("dateTime", Sort.DESCENDING) .between("id", currentPageMinId, currentPageMaxId) .findAll();
额外说明
如果你的id是自增主键(新交易的id一定比旧交易大),那逻辑可以更简化:因为按dateTime倒序和按id倒序的结果是一致的,这时候首次分页可以直接通过排序后的列表提取id范围,省去日期筛选的步骤。
另外,其实Realm原生支持limit()和offset()来实现分页,逻辑更清晰,也不需要依赖id的顺序,如果你后续可以考虑不用between的话,这个方案更简单:
// 首次获取最后20条 int totalCount = realm.where(Transactions.class).count(); int offset = Math.max(totalCount - 20, 0); RealmResults<Transactions> firstPage = realm.where(Transactions.class) .sort("dateTime", Sort.DESCENDING) .offset(offset) .limit(20) .findAll(); // 后续获取更早的20条,每次offset减去20(不能小于0) offset = Math.max(offset - 20, 0); RealmResults<Transactions> nextPage = realm.where(Transactions.class) .sort("dateTime", Sort.DESCENDING) .offset(offset) .limit(20) .findAll();
内容的提问来源于stack exchange,提问作者BekaKK
相关产品推荐
相关产品推荐

