用oracle进行scalikejdbc流式传输

时间:2017-08-02 13:17:24

标签: scala scalikejdbc

我正在使用ScalikeJDBC实现一个流源,需要它来运行多个数据库类型,包括。 Oracle,Sybase等。

文档有点令人困惑,不确定这是否是一个选项:

  

目前,scalikejdbc-streams本身支持MySQL和PostgreSQL。通常使用SQL#iterator工厂方法时,ScalikeJDBC会自动启用所需的设置以使用光标功能。如果您不喜欢该行为,则可以自定义调整DBSession属性

可以通过MySQL和PostgreSQL之外的其他数据库处理流式读取吗?

1 个答案:

答案 0 :(得分:1)

(由于您的问题是关于创建流媒体源,此答案仅针对流媒体支持的发布者方面,而忽略了订阅方。)

支持流式传输需要数据库返回查询一次几行,通常基于游标,而不是一次全部。不同的数据库有不同的方法来启用它。 ScalikeJDBC原生支持对MySQL和PostgreSQL驱动程序使用流iterator方法。也就是说,使用MySQL和PostgreSQL驱动程序,以下工作:

import scalikejdbc._
import scalikejdbc.streams._

// set up a connection pool

import scala.concurrent.ExecutionContext.Implicits.global

val publisher: DatabasePublisher[Int] = DB.readOnlyStream {
  sql"select id from users order by id".map(r => r.get[Int]("id")).iterator
}

由于this

,上述适用于MySQL和PostgreSQL
/**
 * Forcibly changes the database session to be cursor query ready.
 */
val defaultDBSessionForceAdjuster: DBSessionForceAdjuster = (session) => {

  // setup required settings to enable cursor operations
  session.connectionAttributes.driverName match {
    case Some(driver) if driver == "com.mysql.jdbc.Driver" && session.fetchSize.exists(_ > 0) =>
      /*
       * MySQL - https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-implementation-notes.html
       *
       * StreamAction.StreamingInvoker prepares the following required settings in advance:
       *
       * - java.sql.ResultSet.TYPE_FORWARD_ONLY
       * - java.sql.ResultSet.CONCUR_READ_ONLY
       *
       * If the fetchSize is set as 0 or less, we need to forcibly change the value with the Int min value.
       */
      session.fetchSize(Int.MinValue)

    case Some(driver) if driver == "org.postgresql.Driver" =>
      /*
       * PostgreSQL - https://jdbc.postgresql.org/documentation/94/query.html
       *
       * - java.sql.Connection#autocommit false
       * - java.sql.ResultSet.TYPE_FORWARD_ONLY
       */
      session.conn.setAutoCommit(false)

    case _ =>
  }
}

请注意,最后一个case子句意味着ScalikeJDBC默认情况下不 支持使用除MySQL和PostgreSQL之外的驱动程序的流iterator

这并不意味着不能使用其他驱动程序进行流式传输。您引用的文档部分包含以下代码示例:

val publisher: DatabasePublisher[Int] = DB readOnlyStream {
  sql"select id from users".map(r => r.int("id"))
    .iterator
    .withDBSessionForceAdjuster(session => {
      session.conn.setAutoCommit(true)
    })
}

文档说的是,要为MySQL和PostgreSQL之外的数据库启用流式传输,您需要自定义DBSession属性,如上例所示,以便启用游标支持。这种自定义究竟需要什么(例如,调整连接上的fetchSize或禁用autoCommit)取决于驱动程序(假设驱动程序支持一次检索少量行的查询结果) )。