如何使用函数式编程风格在 Scala 中管理数据库连接?

2024-02-13

我有一段使用数据库连接的 Scala 代码:

def getAllProviderCodes()(implicit conf : Configuration) : List[String] = {
  var conn: java.sql.Connection = null
  try {
    conn = DriverManager.getConnection(DBInfo.dbUrl(conf), DBInfo.dbUserName(conf), DBInfo.dbPassword(conf))
    return ResultSetIterator.create(
              conn.prepareStatement("SELECT pcode FROM providers").executeQuery()
           ){_.getString("pcode")}.toList
  } catch {
    case e: Exception =>
      logger.warn("Something went wrong with creating the connection: " + e.getStackTrace)
  } finally {
    if (conn != null) {
      conn.close()
    }
  }
  List()
}

这是非常类似OOP-Java的风格,所以我想知道有没有办法以更实用的方式编写它?我尝试申请成功Try https://www.scala-lang.org/api/2.9.3/scala/util/Try.htmlmonad,但失败了:我最关心的是我们这里有状态,以及finally堵塞。也许这种情况有某种模式?

先感谢您。

UPD:这是来自的示例here https://scalerablog.wordpress.com/2016/05/16/scalera-tip-why-scala-util-try-doesnt-have-finally-clause/恕我直言,解决方案将是什么样子:

val connection = database.getConnection()
val data: Seq[Data] = Try{
  val results = connection.query("select whatever")
  results.map(convertToWhatIneed)
} recover {
  case t: Throwable => 
    Seq.empty[Data]
} get
connection.close()

但正如我在评论中提到的,我必须关闭连接,然后我必须将与连接有关的所有内容放在里面尝试保持纯净......然后我使用“try-catch-finally”进行变体" 在 Try 块内。


我从未使用过 Java SQL Connection 库,因此我的答案的语法已编写为伪代码,但如果我正确理解您的问题,那么我将如何实现您所做的事情:

def getAllProviderCodes()(implicit conf : Configuration): List[String] = {
  val conn: Connection = DriverManager.getConnection(???) // replace ??? with parameters

  val result: List[String] = Try {
    ??? // ResultSetIterator stuff
  } match {
    case Success(output) => output // or whatever .toList thing
    case Failure(_) => List.empty // add logging here
  }

  if(conn != null) conn.close()
  result // will be whatever List you make (or an empty List if Try fails)
}

而不是类似Java的try-catch-finally块,一种类似 Scala 的做事方式是将可能爆炸的东西放在一个Try块并使用以下命令将响应分配给一个值case Success(out) and case Failure(ex).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用函数式编程风格在 Scala 中管理数据库连接? 的相关文章

随机推荐