1

(この質問は、非常によく似た以前のヘルプ リクエストに基づいています。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)
}

my に次のようなものを追加できるようになったので、これは非常に素晴らしいことです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]ます。オブジェクト指向から来て、 のようなことをしたい気がしますがfoos.findByTitle("someFoo")、この機能的なスタイルを行うためのより良い方法があれば、提案をお待ちしています。
  • db.defaultクエリがh2 ドライバーで動作するようにアプリケーション コントローラーから呼び出し、 postgres ドライバーSpecificationで動作するようにテストから呼び出します。db.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.

4

2 に答える 2

2

Scalaの暗黙の変換と暗黙のパラメーターを読む必要があると思います。利用可能なオンライン Scala ブックがあります。

Implicit の欠落に関するエラー メッセージが表示された場合は、ライブラリによって提供された型チェックの失敗に遭遇したことを意味しますが、ここではそうではありません。または、単に Implicit を使用可能にするのを忘れていました。Implicit を使用可能にする方法は 2 つあります。エラーメッセージが表示されるスコープにインポートします。または、基本的に、メソッドのコールサイトへのルックアップを延期します。どちらがプレイに適しているかわかりません。play から暗黙のアプリケーションをインポートするかval dao、メソッドに変換して暗黙の引数リストで暗黙のアプリケーションをリクエストする必要がありますdef dao(implicit app: Application) = ...。または、テストをクラスに変換して、そこでリクエストすることもできます。

于 2014-07-10T07:01:53.033 に答える
1

play slick プラグインを使用する場合、そのプラグインから DB アクセスを使用するコードを呼び出すには、開始された play アプリケーションが必要です。WithApplicationドキュメントで説明されているように、http: //www.playframework.com/documentation/2.3.x/ScalaFunctionalTestingWithSpecs2

于 2014-07-10T07:01:25.723 に答える