Treating an SQL ResultSet like a Scala Stream

前端 未结 10 2239
天涯浪人
天涯浪人 2020-12-02 10:11

When I query a database and receive a (forward-only, read-only) ResultSet back, the ResultSet acts like a list of database rows.

I am trying to find some way to trea

相关标签:
10条回答
  • 2020-12-02 10:36

    i needed something similar. Building on elbowich's very cool answer, I wrapped it a bit, and instead of the string, I return the result (so you can get any column)

    def resultSetItr(resultSet: ResultSet): Stream[ResultSet] = {
        new Iterator[ResultSet] {
          def hasNext = resultSet.next()
          def next() = resultSet
        }.toStream
      }
    

    I needed to access table metadata, but this will work for table rows (could do a stmt.executeQuery(sql) instead of md.getColumns):

     val md = connection.getMetaData()
     val columnItr = resultSetItr( md.getColumns(null, null, "MyTable", null))
          val columns = columnItr.map(col => {
            val columnType = col.getString("TYPE_NAME")
            val columnName = col.getString("COLUMN_NAME")
            val columnSize = col.getString("COLUMN_SIZE")
            new Column(columnName, columnType, columnSize.toInt, false)
          })
    
    0 讨论(0)
  • 2020-12-02 10:40

    I didn't test it, but why wouldn't it work?

    new Iterator[String] {
      def hasNext = resultSet.next()
      def next() = resultSet.getString(1)
    }.toStream
    
    0 讨论(0)
  • 2020-12-02 10:44

    This sounds like a great opportunity for an implicit class. First define the implicit class somewhere:

    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
            }
        }
    }
    

    Next, simply import this implicit class wherever you have executed your query and defined the ResultSet object:

    import com.company.Implicits._
    

    Finally get the data out using the toStream method. For example, get all the ids as shown below:

    val allIds = resultSet.toStream.map(result => result.getInt("id"))
    
    0 讨论(0)
  • 2020-12-02 10:45

    Another variant on the above, which works with Scala 2.12:

    implicit class ResultSetOps(resultSet: ResultSet) {
     def map[T](f: ResultSet => T): Iterator[T] =
      Iterator.continually(resultSet).takeWhile(_.next()).map(f)
    }
    
    0 讨论(0)
提交回复
热议问题