Scala Play Framework Slick 会话不起作用

Posted

技术标签:

【中文标题】Scala Play Framework Slick 会话不起作用【英文标题】:Scala Play Framework Slick session doesn't work 【发布时间】:2013-09-17 14:54:21 【问题描述】:

我正在尝试使用 Slick 和 Play2 框架的简单测试应用程序,但编译器一直抱怨无法推断隐式会话。

这是我的Build.scala

import sbt._
import Keys._
import play.Project._

object ApplicationBuild extends Build 

  val appName         = "dummy"
  val appVersion      = "1.0"

  val appDependencies = Seq(
    jdbc,
    "mysql" % "mysql-connector-java" % "5.1.26",
    "com.typesafe.slick" %% "slick" % "1.0.1"
  )


  val main = play.Project(appName, appVersion, appDependencies).settings(
    // Add your own project settings here      
  )


这是保存我的数据库连接的全局单例:

package models

import play.api.Play.current
import play.api.db.DB
import slick.session.Session
import slick.driver.MySQLDriver.simple._
import scala.slick.session.Database.threadLocalSession


object Global 

  lazy val database = Database.forDataSource(DB.getDataSource())

  lazy val session = database.createSession()


还有我的控制器:

package controllers

import scala.language.implicitConversions
import play.api._
import play.api.mvc._
import models.Global.session

import slick.driver.MySQLDriver.simple._

object Application extends Controller 

  def index = Action 
    /*slick.driver.MySQLDriver.simple.*/Query(Foo).foreach( _ => () ) // Do nothing for now
    Ok(views.html.index("hola"))
  

  object Foo extends Table[(Long, String, String)]("Foo") 
    def * = column[Long]("id") ~ column[String]("bar1") ~ column[String]("bar2")
  


如您所见,我的Global.session val 已导入,但一直提示未找到隐式会话。

【问题讨论】:

你试过'lazy implicit val session = database.createSession()'吗? 是的,我做了,但它仍然不起作用。 除非有充分的理由,否则不要使用 threadLocalSession 或 beginSession。使用 database.withSessionimplicit session : Session => ... 代替有人建议。 【参考方案1】:

要进行查询,您需要两件事:连接到数据库和会话,因此您的问题是如何定义和使用它们。 在Database.threadLocalSession 范围内,您可以像这样进行查询:

Database.forURL("jdbc:h2:mem:play", driver = "org.h2.Driver") withSession 
          //create table
          Foo.ddl.create
          //insert data
          Foo.insert((1.toLong,"foo","bar"))
          //get data
          val data : (Long,String,String) = (forf<-Fooyield(f)).first

或者你可以这样做:

val database  = Database.forDataSource(DB.getDataSource())
 database.withSession implicit session : Session =>
          Foo.ddl.create
          Foo.insert((1.toLong,"foo","bar"))
          val data : (Long,String,String) = (forf<-Fooyield(f)).first

我已经创建了一个测试,它工作正常,你可以玩一下:

"Foo should be creatable " in 
  running(FakeApplication(additionalConfiguration = inMemoryDatabase())) 
    val database  = Database.forDataSource(DB.getDataSource())
    database.withSession implicit session : Session =>
      Foo.ddl.create
      Foo.insert((1.toLong,"foo","bar"))
      val data : (Long,String,String) = (forf<-Fooyield(f)).first

      data._1 must equalTo(1)
    
  

你也可以看看here

【讨论】:

以上是关于Scala Play Framework Slick 会话不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Play framework + Scala:使用动作组合注入依赖

Play Framework Routes 中的 Scala 反引号

Scala + Play Framework + Slick - Json 作为模型字段

在 Play Framework 2.4 中为 Scala 实现 Akka

在 Play Framework 2.4 中为 Scala 实现 CORS

Scala Play Framework Slick 会话不起作用