在 Play for Scala 中断开 Slick JNDI 连接
Disconnect from Slick JNDI connection in Play for Scala
Slick 定义here如何使用 JNDI 连接到数据库:
val db = Database.forName(jndiName: String)
我使用上面的方法连接到 Play for Scala 中的数据库,在 application.conf
中定义 JNDI 连接:
def read (jndi: String, code: Int) = {
val db = Database.forName(jndi)
val records = TableQuery[TableDB]
val action = records.filter(_.code === code).result
val future = db.run(action.asTry)
future.map{
case Success(s) =>
if (s.length>0)
Some(s(0))
else
None
case Failure(e) => throw new Exception ("Failure in read: " + e.getMessage)
}
}
问题是:如何断开与JNDI 资源的连接?只是 db.close()
?有没有办法在read
方法结束时隐式关闭连接?
不清楚是什么让你怀疑它。如果您查看可以创建连接的 forName
, you may see that it just asks JNDI context to get object by the name you provided and then treat it as javax.sql.DataSource
的来源。 DataSource
不是 Closeable
或类似的东西,因此您不必明确释放它。关闭 db
.
就足够了
至于在 read
方法结束时关闭,这可能不是您真正想要的,因为您 return Future
可能仍未完成,因此可能需要连接开放。所以你可能需要的是 Future.onComplete
def read(jndi: String, code: Int) = {
val records = TableQuery[TableDB]
val action = records.filter(_.code === code).result
val db = Database.forName(jndi)
val future = db.run(action.asTry)
future.onComplete(_ => db.close()) // <-- added line
future.map {
case Success(s) =>
if (s.length > 0)
Some(s(0))
else
None
case Failure(e) => throw new Exception("Failure in read: " + e.getMessage)
}
}
您始终可以在应用关闭时使用 play 的关闭挂钩关闭数据库连接(这通常是您想要的),是的 db.close 足以停止连接,您的端口将被释放这就是你应该关心的。我不太确定为什么您希望数据库在该方法之后立即关闭,但是有一个非常简单的解决方法,不会污染代码,您只需将数据库注入该方法即可:
def read(db : Database, code: Int) = {
val records = TableQuery[TableDB]
val action = records.filter(_.code === code).result
val future = db.run(action.asTry)
future.map {
case Success(s) =>
if (s.length > 0)
Some(s(0))
else
None
case Failure(e) => throw new Exception("Failure in read: " + e.getMessage)
}
一旦你得到你想要的结果,这个方法的调用者可以关闭相应的数据库。更安全,更容易改变 :) 另一方面,你总是可以使用@SergGr 的解决方案,它也有效 :)
Slick 定义here如何使用 JNDI 连接到数据库:
val db = Database.forName(jndiName: String)
我使用上面的方法连接到 Play for Scala 中的数据库,在 application.conf
中定义 JNDI 连接:
def read (jndi: String, code: Int) = {
val db = Database.forName(jndi)
val records = TableQuery[TableDB]
val action = records.filter(_.code === code).result
val future = db.run(action.asTry)
future.map{
case Success(s) =>
if (s.length>0)
Some(s(0))
else
None
case Failure(e) => throw new Exception ("Failure in read: " + e.getMessage)
}
}
问题是:如何断开与JNDI 资源的连接?只是 db.close()
?有没有办法在read
方法结束时隐式关闭连接?
不清楚是什么让你怀疑它。如果您查看可以创建连接的 forName
, you may see that it just asks JNDI context to get object by the name you provided and then treat it as javax.sql.DataSource
的来源。 DataSource
不是 Closeable
或类似的东西,因此您不必明确释放它。关闭 db
.
至于在 read
方法结束时关闭,这可能不是您真正想要的,因为您 return Future
可能仍未完成,因此可能需要连接开放。所以你可能需要的是 Future.onComplete
def read(jndi: String, code: Int) = {
val records = TableQuery[TableDB]
val action = records.filter(_.code === code).result
val db = Database.forName(jndi)
val future = db.run(action.asTry)
future.onComplete(_ => db.close()) // <-- added line
future.map {
case Success(s) =>
if (s.length > 0)
Some(s(0))
else
None
case Failure(e) => throw new Exception("Failure in read: " + e.getMessage)
}
}
您始终可以在应用关闭时使用 play 的关闭挂钩关闭数据库连接(这通常是您想要的),是的 db.close 足以停止连接,您的端口将被释放这就是你应该关心的。我不太确定为什么您希望数据库在该方法之后立即关闭,但是有一个非常简单的解决方法,不会污染代码,您只需将数据库注入该方法即可:
def read(db : Database, code: Int) = {
val records = TableQuery[TableDB]
val action = records.filter(_.code === code).result
val future = db.run(action.asTry)
future.map {
case Success(s) =>
if (s.length > 0)
Some(s(0))
else
None
case Failure(e) => throw new Exception("Failure in read: " + e.getMessage)
}
一旦你得到你想要的结果,这个方法的调用者可以关闭相应的数据库。更安全,更容易改变 :) 另一方面,你总是可以使用@SergGr 的解决方案,它也有效 :)