用途:该技能提供一个通用辅助函数,把任意一个基于 (limit, offset) 的分页数据访问函数转换为整表读取,让所有仓储层共用同一条终止规则,而不必各自编写分页循环。
主要能力:函数在循环中按固定页大小请求数据并累积到一个列表,当某一页返回的行数小于页大小时停止,即认为已到末页。调用点保持一行,分页逻辑不会泄漏到仓储层。文档给出了适配后的代码示例,页大小提为常量 PAGE = 100,并用 flow { emit(...) } 配合 flowOn(Dispatchers.IO) 包装调用。
适用场景:导出或备份、一次性批量映射、迁移,或任何调用方确实需要全部行同时驻留内存的消费方。不适用(文档称之为坏味道)的情形:结果随后被过滤、计数、排序或 take(n),这些本应由数据库完成而无需物化整表;用于滚动列表分页更是最明显的误用,因为分页存在的目的就是避免物化全部数据。
使用方式与陷阱:页大小与短页判断必须使用同一个常量;若写死字面量,循环中出现三处页大小(请求参数、终止判断、偏移递增),不一致会静默出错,且若查询自行钳制 limit(如 LIMIT MIN(:limit, 50))也会提前误判结束。循环次数没有上限,若查询忽略 offset 会无限累积直至进程崩溃,需加一行上限。offset 分页需要全序,否则有并列值的排序会使页面重叠,应加主键作为打破并列的排序键。每页是独立事务,读取期间发生写入会移动后续 offset,需要一致快照时应把整个循环包在一个事务中,或改用基于排序列的游标分页(WHERE favoriteAt < :lastSeen)。offset 并非免费,读 M 行、页大小 P 的总代价约为 M²/P 次行访问。结果是 List 而非 Flow,包装后的 flow 在每次收集(包括重组或配置变更重新订阅)时都会重读全表,调用方多次收集时应缓存结果或改用数据库自身的实时 flow。
验证:截断类失败往往返回看似合理的列表,应与数据库自身的计数对比,例如 SELECT COUNT() FROM album WHERE liked = 1;测试夹具的行数需超过一页,并额外加入恰好等于 PAGE 行的边界夹具,此时完整末页会强制一次多余的空查询,若判断写成 size <= PAGE 而丢失末页只在此处暴露。查找需替换的手写分页副本时,用引号包住 include 通配符:grep -rn 'offset += |offset + 100|size < 100' --include='.kt' .
限制:资料未提供官方发布渠道、版本、许可、收费或平台相关信息。