在jOOQ中,如何按需获取、逐行处理并将结果以CSV格式输出?
I currently have code like this:
try (var cursor = query().fetchSize(1000).fetchLazy()) {
cursor.formatCSV(out);
}
这正是我想要的——懒加载获取结果(我的结果量巨大,根本无法全部装入内存),并且正确地将其格式化为CSV。
然而,现在我需要以一种方式对记录进行预处理,使某些记录被拆分成很多条。
类似于:
try (var stream = query().fetchSize(1000).stream()) {
stream
.mapMulti(...) //split the records as needed
.forEach(r -> r.formatCSV(out));
}
但这存在若干问题。首先,输出表头要么对每一行输出,要么根本不输出,取决于我传入的格式。此外,在记录上调用 formatCSV() 会先把记录包装在一个 Result 中,在我的场景里意味着为数千万个对象分配内存,几乎等于白费。
我该如何解决这些问题?
解决方案
首先,我将根据传入的格式要么对每一行打印表头,要么根本不打印表头。
把包含表头的格式仅用于第一条记录,或者基于 Cursor.fields() 创建一个不包含任何记录的假 Result,并打印该结果的表头。
在我的场景里,这意味着为几千万个对象分配内存,基本上等于白费。
你是否有任何基准测试来证明这确实会成为问题?Result 其实只是一个 ArrayList,在这种情况下每条记录只有一个元素。也许会更好,是的。但难道那么糟糕吗?逃逸分析也许会生效,你会没事。与正在发生的实际输入/输出相比,这点开销就不值一提……
另一种方法是把记录分块收集到你自己的 Result 实例中(例如每块100条),然后把每块整体导出为CSV。
如果这是一个显著的问题,为什么不提交一个 bug?
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。