我正在使用Play 2.2在Scala中创建一个应用程序。我正在play-slick 0.5.0.8
用作我的MySQL DB连接器。我有以下应用程序控制器:
package controllers
import models._
import models.database._
import play.api._
import play.api.mvc._
import play.api.Play.current
import play.api.db.slick._
object Application extends Controller {
// WORKS:
def test = DBAction {
implicit session => Ok(views.html.test(Cameras.findById(1)))
}
// DOES NOT WORK:
def photo = Action {
val p = PhotoFetcher.fetchRandomDisplayPhoto(someParametersBlah))
Ok(views.html.photo(p))
}
}
如您所见,test
DBAction可以正常工作,并且可以从数据库中获取照片。不幸的是,该photo
行动不起作用。
我PhotoFetcher.fetchRandomDisplayPhoto(blah)
做了很多不同的事情。它的内部包含对的调用Cameras.findById(blah)
,该调用应返回一个Camera
对象(在test
DBAction中有效)。但是,使用此配置,我得到以下错误:
could not find implicit value for parameter s: slick.driver.MySQLDriver.simple.Session
我试图将photo
Action变成DBAction,如下所示:
def photo = DBAction {
implicit session => {
val p = PhotoFetcher.fetchRandomDisplayPhoto(someParametersBlah))
Ok(views.html.photo(p))
}
}
但这只会导致相同的丢失会话错误。就像PhotoFetcher不知道隐式会话一样。
我尝试过的另一件事是将slick.session.Database.threadLocalSession
my导入PhotoFetcher
,但这只会导致以下错误:
SQLException: No implicit session available; threadLocalSession can only be used within a withSession block
如果有帮助,这是我的Cameras
对象的简化版本:
package models.database
import models.Format.Format
import scala.slick.driver.MySQLDriver.simple._
case class Camera(id: Long,
otherStuff: String)
trait CamerasComponent {
val Cameras: Cameras
class Cameras extends Table[Camera]("cameras") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def otherStuff = column[String]("otherStuff", O.NotNull)
def * = id ~ otherStuff <> (Camera.apply _, Camera.unapply _)
val byId = createFinderBy(_.id)
val byOtherStuff = createFinderBy(_.otherStuff)
}
}
object Cameras extends DAO {
def insert(camera: Camera)(implicit s: Session) { Cameras.insert(camera) }
def findById(id: Long)(implicit s: Session): Option[Camera] = Cameras.byId(id).firstOption
def findByOtherStuff(otherStuff: String)(implicit s: Session): Option[Camera] = Cameras.byOtherStuff(model).firstOption
}
所以,好像我已经在某个地方交叉了。现在,我只能直接从Controller DBAction访问我的DAO对象,而不能从某个不同类的内部访问。任何帮助,将不胜感激。谢谢!
您的定义是否PhotoFetcher.fetchRandomDisplayPhoto.fetchRandomDisplayPhoto
包含隐式会话?
// PhotoFetcher
def fetchRandomDisplayPhoto(args: Blah*)(implicit s: Session) = {
// ...
val maybeCam = Cameras.findById(blah) // <- sees the implicit session
// ...
}
还是您依赖threadLocalsession
in PhotoFetcher
?(没有的隐式会话参数fetchRandomDisplayPhoto
)?
尽管Slick的threadLocalSession对于快速尝试一些东西很方便,但稍后可能会导致混乱和清晰度下降。最好只(implicit s: Session)
对所有调用Slick模型的方法使用明确的参数列表。这也可以很好地与配合DBAction
,让框架管理会话。
缺点是您必须拥有(implicit s: Session)
所有方法-像这样的解决方法:https : //github.com/freekh/play-slick/issues/20
Scala不是冗长的,并且非常适合重构-因此,我建议您在进入桥梁时考虑将其过桥,并DBAction
用于执行数据库工作的所有操作;为所有调用数据库模型的方法提供一个隐式会话,并查看为您带来的收益。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句