Ral*_*lph 43 scala resultset stream
当我查询数据库并接收(仅向前,只读)ResultSet时,ResultSet就像一个数据库行列表.
我试图找到一些方法来像Scala一样对待这个ResultSet Stream
.这将允许这样的操作的filter
,map
等等,而不是消耗大量的内存.
我实现了一个尾递归方法来提取单个项目,但是这要求所有项目同时在内存中,如果ResultSet非常大,则会出现问题:
// Iterate through the result set and gather all of the String values into a list
// then return that list
@tailrec
def loop(resultSet: ResultSet,
accumulator: List[String] = List()): List[String] = {
if (!resultSet.next) accumulator.reverse
else {
val value = resultSet.getString(1)
loop(resultSet, value +: accumulator)
}
}
Run Code Online (Sandbox Code Playgroud)
elb*_*ich 73
我没有测试它,但为什么它不起作用?
new Iterator[String] {
def hasNext = resultSet.next()
def next() = resultSet.getString(1)
}.toStream
Run Code Online (Sandbox Code Playgroud)
hra*_*ban 10
@ elbowich答案的效用函数:
def results[T](resultSet: ResultSet)(f: ResultSet => T) = {
new Iterator[T] {
def hasNext = resultSet.next()
def next() = f(resultSet)
}
}
Run Code Online (Sandbox Code Playgroud)
允许您使用类型推断.例如:
stmt.execute("SELECT mystr, myint FROM mytable")
// Example 1:
val it = results(stmt.resultSet) {
case rs => rs.getString(1) -> 100 * rs.getInt(2)
}
val m = it.toMap // Map[String, Int]
// Example 2:
val it = results(stmt.resultSet)(_.getString(1))
Run Code Online (Sandbox Code Playgroud)
对于一个隐含的课程来说,这听起来像是一个很好 首先在某处定义隐式类:
import java.sql.ResultSet
object Implicits {
implicit class ResultSetStream(resultSet: ResultSet) {
def toStream: Stream[ResultSet] = {
new Iterator[ResultSet] {
def hasNext = resultSet.next()
def next() = resultSet
}.toStream
}
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,只需在执行查询的任何位置导入此隐式类,并定义ResultSet对象:
import com.company.Implicits._
Run Code Online (Sandbox Code Playgroud)
最后使用toStream方法获取数据.例如,获取所有ID,如下所示:
val allIds = resultSet.toStream.map(result => result.getInt("id"))
Run Code Online (Sandbox Code Playgroud)