Scala:通过生成器公开 JDBC 结果集(可迭代)
我在数据库中有一组行,我想提供一个接口来旋转它们,如下所示:
def findAll: Iterable[MyObject]
我们不需要同时将所有实例都存储在内存中。在 C# 中,您可以使用 Yield 轻松创建这样的生成器,编译器负责将循环记录集的代码转换为迭代器(某种程度的反转)。
我当前的代码如下所示:
def findAll: List[MyObject] = {
val rs = getRs
val values = new ListBuffer[MyObject]
while ( rs.next() )
values += new valueFromResultSet(rs)
values.toList
}
有没有办法可以将其转换为不将整个集合存储在内存中?也许我可以用 a 来理解?
I've got a set of rows in a database, and I'd like to provide an interface to spin through them like this:
def findAll: Iterable[MyObject]
Where we don't require having all the instances in memory at once. In C# you can easily create generators like this using yield, the compiler takes care of converting code that loops through the recordset into an iterator (sort of inverting it).
My current code looks like this:
def findAll: List[MyObject] = {
val rs = getRs
val values = new ListBuffer[MyObject]
while ( rs.next() )
values += new valueFromResultSet(rs)
values.toList
}
Is there a way I could convert this to not store the entire set in memory? Perhaps I could use a for comprehension?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我遇到了同样的问题,基于上面的想法,我通过简单地编写一个适配器类创建了以下解决方案:
有了这个,您可以对结果集执行map操作 - 这是我个人的意图:
附加
.toList
以强制评估。如果在使用这些值之前关闭数据库连接,这非常有用。否则,您将收到错误消息,指出连接关闭后无法访问 ResultSet。I came across the same problem and based on the ideas above I created the following solution by simply writing an adapter class:
With this you can e.g. perform map operations on the result set - which was my personal intention:
Append a
.toList
in order to force evaluation. This is useful if the database connection is closed before you use the values. Otherwise you will get an error saying that you cannot access the ResultSet after the connection was closed.尝试扩展 Iterator。我还没有测试过它,但是是这样的:
这应该在调用时存储 rs,否则只是调用 rs 的轻量级包装器。
如果您想保存遍历的值,请查看 Stream。
Try extending Iterator instead. I haven't tested it, but something like this:
This should store rs when it's called, and otherwise just be a light wrapper to calls to rs.
If you want to save the values that you traverse, check out Stream.
实现相同目的的更简单(惯用)方法是
您需要
.toList
来强制求值,否则底层集合将是一个流,并且 ResultSet 可能会在求值发生之前关闭。A simpler (idiomatic) way to achieve the same would be
You need the
.toList
to force evaluation, otherwise the underlying collection will be a stream and the ResultSet may be closed before evaluation has taken place.我在 Scala 2.13 中设计了一个解决方案,通过使用包含
.map()
方法的隐式类
来增强ResultSet
。对于较少数量的行,要这样使用:
记住最后的
.toList
至关重要,因为它会导致Iterator
遍历ResultSet< /代码>。
对于不希望耗尽内存的大量行,替代方法是使用
.foreach()
进行工作,如下所示:I devised a solution in Scala 2.13 by enhancing
ResultSet
with animplicit class
containing a.map()
method.To be used like this for smaller quantities of rows:
It is critically important to remember the
.toList
at the end as that causes theIterator
to traverse theResultSet
.For larger quantities of rows where it is undesirable to use up the memory, the alternative is to do the work with a
.foreach()
, like this: