(这个问题是基于一个非常相似的previous request for help。随着DAO和多个数据库驱动程序的引入,同样的问题需要采用不同的方法,我希望保证一个新的SO问题。)
我有一个class
和Slick 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
,并自动获取db.default
中application.conf
的驱动程序和数据库网址。
以类似但不太好的方式,我可以在我的测试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驱动程序一起使用。< / LI>
顺便说一句,如果我可以把它放在我的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
。
答案 0 :(得分:2)
我认为您需要阅读Scala中的隐式转换和隐式参数。有在线Scala书籍。
当您收到有关缺失隐式的错误消息时,或者意味着您遇到了由库提供的失败类型检查,这会阻止您做错事,但事实并非如此。或者你只是忘了隐含可用。有两种方法可以使隐式可用。将其导入到您收到错误消息的范围。或者基本上将查找推迟到您方法的调用点。不确定哪一个是正确的游戏。您需要从play中导入隐式Application,或者需要将val dao
转换为方法并在隐式参数列表def dao(implicit app: Application) = ...
中请求隐式应用程序。您也可以将测试变成一个类并在那里请求它。
答案 1 :(得分:1)
如果您使用播放光滑插件,它将需要一个启动播放应用程序,以便能够调用使用该插件的数据库访问的代码,您可以确保使用WithApplication
在测试中启动播放应用程序如文档中所述:http://www.playframework.com/documentation/2.3.x/ScalaFunctionalTestingWithSpecs2