我是Slick的新手,我正在努力解决导致我的一些问题。
在我的数据库中,我使用我的电子邮件地址保存了一个用户。但是,当我执行此方法(在DAO中实现)时:
def getByEmail(email: String): Future[Option[User]] = {
println(s":${email}:")
println(db.run(users.filter(_.email === email).result.headOption).value)
db.run(users.filter(_.email === email).result.headOption)
}
打印结果为无(我可以验证电子邮件是否存在)。
我的application.conf设置如下:
slick.dbs.default.profile = "slick.jdbc.PostgresProfile$"
slick.dbs.default.db.driver = "org.postgresql.Driver"
slick.dbs.default.db.url = "jdbc:postgresql://localhost:5432/databasename"
整个DAO实现为:
package dao
import javax.inject.{Inject, Singleton}
import models.User
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.jdbc.{JdbcProfile, PostgresProfile}
import slick.lifted.ProvenShape
import scala.concurrent.{ExecutionContext, Future}
/**
* Created by Marin on 08/09/2017.
*/
@Singleton
class UserDAO @Inject()(val dbConfigProvider: DatabaseConfigProvider)(implicit ec: ExecutionContext) extends HasDatabaseConfigProvider[PostgresProfile] {
import profile.api._
private class UserTable(tag: Tag) extends Table[User](tag, "users") {
def id: Rep[Long] = column[Long]("id", O.PrimaryKey, O.AutoInc)
def email: Rep[String] = column[String]("email", O.Unique)
def name: Rep[String] = column[String]("name")
def surname: Rep[String] = column[String]("surname")
override def * : ProvenShape[User] = (id.?, email, name.?, surname.?) <> (User.tupled, User.unapply)
}
private val users = TableQuery[UserTable]
def add(user: User): Future[User] = {
val query = users returning users.map(_.id) into ((user, id) => user.copy(id = Some(id)))
db.run(query += user)
}
def get(id: Long): Future[Option[User]] = {
db.run(users.filter(_.id === id).result.headOption)
}
def getByEmail(email: String): Future[Option[User]] = {
println(s":${email}:")
println(db.run(users.filter(_.email === email).result.headOption).value)
db.run(users.filter(_.email === email).result.headOption)
}
def listAll: Future[Seq[User]] = {
db.run(users.result)
}
}
我不明白为什么结果仍然是无...我发现这个问题,因为我注意到我的Play控制器中的一些Future从未完成......
答案 0 :(得分:1)
对db.run(...)
的调用结果为Future
。根据{{3}}:
如果未来未完成,则返回值为
None
。
您访问结果的方式是在.value
的调用返回后立即调用db.run
。这并没有给Slick足够的时间来打开连接,执行语句并返回结果。因此,您获得了None
。
关于控制器Future
永远不会完成的评论,这一点也很明显。如果是这种情况,则对.value
的调用将始终返回None
。