当使用带有油滑2.0 DAO的时候把我的数据库访问方法?(Where to put my datab

2019-10-20 10:16发布

(这个问题是基于一个非常类似的帮助以前的要求 。通过引入一个DAO和多个数据库驱动程序的,同样的问题需要不同的方法,我希望保证新的SO问题。)

我有一个class和光滑Table像这样定义的:

import play.api.db.slick.Profile

case class Foo(title: String, description: String, id: Int = 0)

trait FooComponent extends Profile { this: Profile =>
  import profile.simple._

  class FooTable(tag: Tag) extends Table[Foo](tag, "FOO") {

    def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
    def title = column[String]("TITLE", O.NotNull)
    def description = column[String]("DESCRIPTION")

    def * = (title, description, id) <> (Foo.tupled, Foo.unapply)
  }
}

和数据访问对象:

class DAO(override val profile: JdbcProfile) extends FooComponent with Profile {
  val foos = TableQuery[FooTable]
}

object current {
  val dao = new DAO(DB(play.api.Play.current).driver)
}

这是相当真棒,因为现在我可以像下面这样我补充一下application.conf

db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"

db.test.driver=org.postgresql.Driver
db.test.user="testuser"
db.test.password=""
db.test.url="jdbc:postgresql:testdb"

...如果我做一个控制器的情况如下:

import models.current.dao._
import models.current.dao.profile.simple._

我可以访问我foos TableQuery ,它自动地获取给定的驱动程序和数据库URL db.defaultapplication.conf

在一个类似的,但不-相当-AS-很好的方式,我可以做我的试验中,以下Specification

"test Foos" in new WithApplication() {
  val dao = new DAO(play.api.db.slick.DB("test").driver)
  import dao._ //import all our database Tables
  import dao.profile.simple._ //import specific database methods

  play.api.db.slick.DB("test").withSession { implicit s: Session =>
    println(s.conn.getMetaData.getURL)
    println(foos.list)
  }

但是,如果我想要什么来定义它可以在一个行动的方法TableQuery[Foo] ? 事情是这样的:

def findByTitle(title: String) = foos.filter(_.id === id).list

问题

什么是写作的正确方式findByTitle方法,我应该在哪里把它让我可以:

  • 说它的方式,使得它不会与作用于同名的方法碰撞TableQuery[Bar] 。 从OO来了,我觉得我要像做foos.findByTitle("someFoo")但如果有这样的功能,风格的一个更好的方法,我很开放的建议。
  • 从应用程序控制器调用它使得查询将与我的工作db.default H2驱动器,并从我的测试Specification ,这样它会与我的工作db.test Postgres的驱动程序。

顺便说一句,如果我可以把这个在我的DAO:

object current {
  val dao = new DAO(DB(play.api.Play.current).driver)
}

然后import models.dao.current._任何地方我想用这个DAO,我怎么能相同的形式延伸到以下几点:

object test {
  val dao = new DAO(play.api.db.slick.DB("test").driver)
}

如果我尝试这样做,编译器抱怨没有an implicit Application in scope

Answer 1:

我认为你有必要隐式转换和隐斯卡拉参数阅读起来。 有可用的在线书籍的Scala。

当你得到关于丢失隐含的错误信息,要么意味着你跑进由库防止你做错事提供一个失败型检查,但这里并非如此。 或者你根本都忘了,使隐含可用。 有两种方法可以让一个隐含可用。 无论是将其导入到你在哪里得到错误信息的范围。 或基本上延迟的查找到你的方法的调用点。 不知道哪一个是发挥正确的。 您可能需要从游戏中导入隐含的应用程序,或者你需要把val dao成的方法和在一个隐含参数列表请求隐式应用def dao(implicit app: Application) = ... 。 您也可以把测试变成一个类,并要求它。



Answer 2:

如果您使用播放光滑插件,它需要一个开始播放应用能够调用使用从该插件数据库访问代码,你可以确保开始使用您的测试播放应用WithApplication如文档描述: HTTP ://www.playframework.com/documentation/2.3.x/ScalaFunctionalTestingWithSpecs2



文章来源: Where to put my database access methods when using a DAO with Slick 2.0?