我有一段使用数据库连接的 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(使用前将#替换为@)