【问题标题】:Struggling with generic(s) repository methods与通用存储库方法作斗争
【发布时间】:2017-01-22 22:45:48
【问题描述】:

我有一个语言模型、表和存储库。到目前为止,这是可行的:

    package repositories

import javax.inject.Inject

import Helper
import model.{Language, LanguageModel}
import play.api.Logger
import play.api.cache.SyncCacheApi
import slick.jdbc.JdbcProfile

import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}

class LanguageRepository @Inject()(cache: SyncCacheApi, jdbcProfile: JdbcProfile, implicit val executionContext: ExecutionContext)
{
  private val model = new LanguageModel(jdbcProfile)

  import jdbcProfile.api._

  def all(userName: String): Future[Seq[Language]] =
  {
    cache.get[Future[Seq[Language]]](buildCacheKey(userName)) match
    {
      case Some(x) => {Logger.info("[LanguageRepository](all) Found something in cache"); x}
      case None => {
        Logger.info("[LanguageRepository](all) Nothing useful to be found in cache, calling database now")
        val result = retrieve(userName)
        result.onComplete{
          case Success(value) => if(!value.isEmpty) cache.set(buildCacheKey(userName), result)
          case Failure(e) => ()
        }

        result
      }
    }
  }

  private def retrieve(userName: String): Future[Seq[Language]] =
  {
    // TODO extract this to a repositoryTrait and implement fallbacks etc
    val db = Database.forURL(Helper.getDbUrl(), driver = Helper.getDbDriver())

    db.run(model.all.result)
  }

  private def buildCacheKey(userName: String): String = s"$userName.languages"
}

现在我正在与过去的今天离开现在的我挣扎。

所以我创建了这个特性,并希望让它由 LanguageRepository 扩展,以摆脱对所有存储库/模型都应该相同的通用检索方法。但遗憾的是到目前为止还没有运气:

trait Repository
{
  type Entity
  val model: Base
  val profile: JdbcProfile

  import profile.api._

  protected def retrieve(userName: String): Future[Seq[Entity]] =
  {
    val db = Database.forURL(Helper.getDbUrl(), driver = Helper.getDbDriver())      
    db.run(model.all.result)
  }
}

这是基地:

trait Base
{
  val dbProfile: JdbcProfile
  import dbProfile.api._

  type Entity
  type EntityTable <: Table[Entity]
  lazy val all = TableQuery[EntityTable]
}

这里出现一个错误 >> 需要类类型,但找到了 Base.this.EntityTable

class LanguageModel(databaseProfile: JdbcProfile) extends Base
  {
    override val dbProfile: JdbcProfile = databaseProfile
    import dbProfile.api._

    ...

    override type EntityTable = LanguageTable
  }

存储库本身也没有编译,因为类型不匹配。有多个问题,我不知道从哪里开始解决它们。

【问题讨论】:

    标签: scala generics slick-3.0


    【解决方案1】:

    您的基表定义不会那样工作。您需要类类型,也许您应该使用泛型。此外,与其创建多个抽象,不如从一个抽象开始并从那里发展。尝试以下方式:

    class Repository[A, B <: Table[A]](t: TableQuery[B]) {
        val model = t
        //protected def retrieve ..
    }
    
    class LanguageModel(databaseProfile: JdbcProfile) extends Repository[Language, LanguageTable](TableQuery[LanguageTable]) {
        //...
    }
    

    首先编译所有内容,然后开始一次添加一个抽象类。

    【讨论】:

    • 虽然模型没有存储库
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 2013-12-06
    • 2019-04-20
    相关资源
    最近更新 更多