如何在不加载全部数据到内存的情况下遍历SqlDelight查询结果?
SqlDelight 大表逐行查询方案探讨
我观察到SqlDelight的Query对象没有可替代executeAsList()的逐行查询方法——executeAsList()会一次性加载全部数据,无法直接用于处理大表(内存无法承载全量数据)。
现有两种接近需求但存在缺陷的方案:
- 使用
execute()函数:允许逐行处理结果,但会丢失类型安全性,需要手动处理原生SQLite列的类型转换:
val a = mDb.testQueries.selectAll().execute { cursor -> while (cursor.next().value) { println("cursor $cursor") } QueryResult.Unit }
- 传入映射器构造查询:能恢复类型安全性,但必须调用
executeAsList()返回全量结果列表,依然会因加载整张表数据而浪费内存:
mDb.testQueries.selectAll { id, foo, bar, timestamp -> println("Running on id $id, timestamp $timestamp") }.executeAsList()
除了自行编写分页代码外,真的没有其他查询大表的方法吗?
更新:可行的扩展函数方案
基于Stack Overflow回答实现的扩展函数,既支持逐行处理,又保留了类型安全性:
fun <RowType : Any> Query<RowType>.iterate(block: (RowType) -> Unit) { execute { cursor -> while (cursor.next().value) { block(mapper(cursor)) } QueryResult.Unit } } // 使用示例 mDb.testQueries.selectAll().iterate { id, foo, bar, timestamp -> // 此处编写逐行处理逻辑 }
内容的提问来源于stack exchange,提问作者Grzegorz Adam Hankiewicz
相关产品推荐
相关产品推荐

