Seb*_*ian 1 session scala implicit playframework slick
我是Slick和Scala的新手.首先看一下我的示例表,其中包含用于查询的case类映射和帮助器SuitsManager
.现在SuitsManager
玩的方法被Play调用!DBAction中的控制器(我正在使用play-slick 0.6.0.1).
package models
import play.api.db.slick._
import play.api.db.slick.Config.driver.simple._
import scala.collection.immutable.HashMap
import scala.slick.jdbc.JdbcBackend
case class Suit(id:Option[Long],
complainant: String,
defender: String,
litigation: Long,
litigationValue: BigDecimal,
status: Long)
class Suits(tag: Tag) extends Table[Suit](tag, "SUITS") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def complainant = column[String]("complainant")
def defender = column[String]("defender")
def litigation = column[Long]("litigation")
def litigationValue = column[BigDecimal]("litigationValue")
def status = column[Long]("status")
def * = (id.?, complainant, defender, litigation, litigationValue, status) <> (Suit.tupled, Suit.unapply)
}
object SuitsManager {
val suits = TableQuery[Suits]
def list(offset: Int, limit: Int, filter: String = "%")(implicit session: JdbcBackend#Session) = {
suits.filter(_.defender like "%").drop(offset).take(limit).list
}
def count(offset: Int, limit: Int, filter: String = "%") : Long = {
suits.filter(_.defender like "%").drop(offset).take(limit).length.run
}
}
Run Code Online (Sandbox Code Playgroud)
现在看一下SuitsController
第一个编译中的2个方法,因为它声明了隐式会话参数.第二个给出编译错误:
could not find implicit value for parameter session: play.api.db.slick.Config.driver.Backend#Session
Run Code Online (Sandbox Code Playgroud)
因此,为查询创建辅助对象似乎不是很优雅.如果没有声明隐式会话参数,还有其他方法吗?也许使用导入?我的第二个问题:会话参数类型JdbcBackend#Session
是否正确?为什么不只是Session?
第一个问题:
不可能避免Session
以某种方式绕过.
Session
您传递的隐含不是您的应用程序的一些全局信息.该Session
对象表示您与数据库的当前打开会话.使用Play Slick,当向a发出请求时,将为您打开此数据库会话DBAction
.
这意味着您Session
的HTTP请求仅可用,并且严格依赖于该请求.事实上,你会发现它是implicit request =>
每个人都注意到的一个领域DBAction
:
val someAction = DBAction { implicit request => // DBAction opens database session, and puts it in request.dbSession
// Database session for this request is implicitly available on
// the scope here and therefore may be passed to other methods implicitly
} // Database session is closed
Run Code Online (Sandbox Code Playgroud)
因此,每个请求都有一个新的,不同的数据库会话.此外,每个数据库交互都需要数据库会话.因此,每个执行某些查询的方法都需要提供Session
您处理特定请求的当前流量.
implicits通常用于此的原因是因为它为传递此会话提供了最干净的代码.
// With implicits
def helperMethod1(param: Any)(implicit s: Session) = someQuery1.list // Session is passed implicitly
def helperMethod2(param: Any)(implicit s: Session) = someQuery2.exists.run // Session is passed implicitly
def action = DBAction { implicit request =>
// Stuff
helperMethod1(param1) // request.dbSession is passed implicitly
// Stuff
helperMethod2(param2) // request.dbSession is passed implicitly
// Stuff
}
Run Code Online (Sandbox Code Playgroud)
而且重复性更强
// Without implicits
def helperMethod1(param: Any, s: Session) = someQuery.list(s) // Must pass Session explicitly
def helperMethod2(param: Any, s: Session) = someQuery.exists.run(s)
def action = DBAction { implicit request =>
val session = request.dbSession
// Stuff
helperMethod1(param1, session) // Have to repeat session for every DB call
// Stuff
helperMethod2(param2, session)
// Stuff
}
Run Code Online (Sandbox Code Playgroud)
@cvogt提到的Slick文档问题中的示例不是解决问题的好方法,因为它不会减少在这种情况下需要传递的参数数量.
第二个问题:
一般来说,Session
是一个所谓的类型别名JdbcBackend#Session
.这意味着type Session = JdbcBackend#Session
,即它们完全相同.您可以安全地使用Session
任何代码,但不幸的是,Play控制器代码.
原因是Play控制器也定义了一种类型Session
.Play's Session
代表当前的HTTP会话,基于用户设置的cookie.不幸的是,这个命名与Slick的冲突Session
.
要解决此问题,您可以为导入设置别名:import scala.slick.driver.JdbcProfile.simple.{Session => SlickSession}
.
归档时间: |
|
查看次数: |
4306 次 |
最近记录: |