Ale*_*ack 14 iterable scala jdbc
我在数据库中有一组行,我想提供一个接口来像这样旋转它们:
def findAll: Iterable[MyObject]
Run Code Online (Sandbox Code Playgroud)
我们不需要同时在内存中包含所有实例.在C#中,您可以使用yield轻松创建这样的生成器,编译器负责将循环通过记录集的代码转换为迭代器(将其反转).
我当前的代码如下所示:
def findAll: List[MyObject] = {
val rs = getRs
val values = new ListBuffer[MyObject]
while ( rs.next() )
values += new valueFromResultSet(rs)
values.toList
}
Run Code Online (Sandbox Code Playgroud)
有没有办法可以将其转换为不将整个集存储在内存中?也许我可以使用一个理解?
Rex*_*err 14
尝试扩展Iterator.我还没有测试过,但是这样的话:
def findAll: Iterator[MyObject] = new Iterator[MyObject] {
val rs = getRs
override def hasNext = rs.hasNext
override def next = new valueFromResultSet(rs.next)
}
Run Code Online (Sandbox Code Playgroud)
这应该在调用时存储rs,否则只是调用rs的轻量级包装器.
如果要保存遍历的值,请查看Stream.
Bjö*_*obs 13
我遇到了同样的问题,基于上面的想法,我通过编写适配器类创建了以下解决方案:
class RsIterator(rs: ResultSet) extends Iterator[ResultSet] {
def hasNext: Boolean = rs.next()
def next(): ResultSet = rs
}
Run Code Online (Sandbox Code Playgroud)
有了这个,您可以例如对结果集执行地图操作 - 这是我个人的意图:
val x = new RsIterator(resultSet).map(x => {
(x.getString("column1"), x.getInt("column2"))
})
Run Code Online (Sandbox Code Playgroud)
附加一个.toList以强制评估.如果在使用值之前关闭数据库连接,这将非常有用.否则,您将收到一条错误消息,指出在关闭连接后无法访问ResultSet.
一种更简单(惯用)的方法就是实现同样的目标
Iterator.continually((rs.next(), rs)).takeWhile(_._1).map(r => valueFromResultSet(r._2)).toList
Run Code Online (Sandbox Code Playgroud)
您需要.toList强制评估,否则底层集合将是一个流,并且可以在评估发生之前关闭ResultSet.
| 归档时间: |
|
| 查看次数: |
6895 次 |
| 最近记录: |