在Slick 2.0中使用DAO时,我的数据库访问方法放在哪里? [英] Where to put my database access methods when using a DAO with Slick 2.0?

查看:98
本文介绍了在Slick 2.0中使用DAO时,我的数据库访问方法放在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(此问题基于一个非常相似的

(This question is based on a very similar previous request for help. With the introduction of a DAO and multiple database drivers, the same problem requires a different approach, and I hope warrants a new SO question.)

我有一个class和光滑的Table定义如下:

I have a class and Slick Table defined like this:

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)
  }
}

还有一个数据访问对象:

And a data access object:

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中添加以下内容:

This is pretty awesome, because now I can add something like the following to 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"

...,如果我在Controller中执行以下操作:

... and if I do the following in a Controller:

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

我可以访问我的foos TableQuery,它会自动获取application.conf中为db.default给出的驱动程序和数据库URL.

I have access to my foos TableQuery, and it automagically gets the driver and database url given for db.default in application.conf.

以类似但不十分巧妙的方式,我可以在测试Specification中执行以下操作:

In a similar, but not-quite-as-nice way, I can do the following in my test 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]起作用的方法怎么办?像这样:

However, what if I want to define a method which can act on a TableQuery[Foo]? Something like this:

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


问题

编写findByTitle方法的正确方法是什么,应该在哪里放置以便可以:

What's the correct way of writing the findByTitle method, and where should I put it so that I can:

  • 以一种不会与作用于TableQuery[Bar]的同名方法相冲突的方式进行调用.来自OO,我感觉我想做类似foos.findByTitle("someFoo")的事情,但是如果有一种更好的方法来实现这种功能风格,我可以提出建议.
  • 从应用程序控制器中调用它,以便该查询将与我的db.default h2驱动程序一起使用,并与我的测试Specification一起使用,以便该查询将与我的db.test postgres驱动程序一起使用.
  • Call it in a way such that it won't collide with a method of the same name which acts on TableQuery[Bar]. Coming from OO, I feel like I want to do something like foos.findByTitle("someFoo"), but if there's a better way of doing this functional-style, I'm open to suggestions.
  • Call it from an application Controller such that the query will work with my db.default h2 driver, and from my test Specification so that it will work with my db.test postgres driver.

顺便说一句,如果我可以把它放在我的DAO中:

As an aside, if I can put this in my DAO:

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

然后import models.dao.current._在任何我想使用此DAO的地方,如何将相同的形式扩展到以下内容:

and then import models.dao.current._ anywhere I want to use this DAO, how can I extend the same form to the following:

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

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

If I try to do this, the compiler complains about not having an implicit Application in scope.

推荐答案

我认为您需要阅读Scala中的隐式转换和隐式参数.有在线Scala书籍.

I think you need to read up in implicit conversion and implicit parameters in Scala. There are online Scala books available.

当您收到有关缺少隐式信息的错误消息时,它要么意味着您遇到了库提供的类型检查失败,从而阻止了您做错事,但是事实并非如此.或者,您只是忘记了使隐式可用.有两种方法可以使隐式可用.要么将其导入到您收到错误消息的作用域中.或者基本上将查找推迟到您的方法的调用站点.不知道哪一个适合玩.您可能需要从游戏中导入隐式应用程序,或者需要将val dao转换为方法并在隐式参数列表def dao(implicit app: Application) = ...中请求隐式应用程序.您也可以将test变成一门课,然后在那儿要求.

When you get an error message about a missing implicit it either means you ran into a failing type-check provided by a library preventing you from doing something wrong, but that's not the case here. Or you simply forgot to make the implicit available. There are two ways to make an implicit available. Either import it into the scope where you get the error message. Or basically defer the lookup to the callsite of your method. Not sure which one is the right one for play. You either need to import the implicit Application from play, or you need turn val dao into a method and request an implicit application in an implicit argument list def dao(implicit app: Application) = .... You can alternatively turn test into a class and request it there.

这篇关于在Slick 2.0中使用DAO时,我的数据库访问方法放在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆