(Этот вопрос основан на очень похожий previous request for help. С введением в DAO и нескольких драйверов база данных, такая же проблема требует иного подхода, и я надеюсь, что гарантирует отсутствие нового SO вопрос.)Где разместить методы доступа к базе данных при использовании DAO с Slick 2.0?
У меня есть 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
, и он автоматически получает URL-адрес драйвера и базы данных для 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")
, но если есть лучший способ сделать этот функциональный стиль, я открыт для предложений. - Позвоните из приложения Контроллер, чтобы запрос работал с моим водителем h2
db.default
, и из моего тестаSpecification
, чтобы он работал с моим драйвером postgresdb.test
.
Как и в стороне, если я могу сделать это в моей 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
.
Для кого-то, кто был смущен (как и я), о том, почему мой DAO не содержит «Таблицу» и имеет класс DAO (переопределить val-профиль: JdbcProfile), расширяет FooComponent с помощью Profile' вместо 'class DAO (val driver: JdbcProfile) ', как вы можете видеть в других примерах, я использую плагин play-slick. Проверьте различия между этими двумя примерами: [play-slick] (https://github.com/playframework/play-slick/blob/master/samples/play-slick-cake-sample/app/models/DAO.scala) и [slick] (https://github.com/slick/slick-examples/blob/master/src/main/scala/com/typesafe/slick/examples/lifted/MultiDBExample.scala) ... – sjwarner