我有一个语言模型,表和存储库。到目前为止,这有效:
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]
}
这里我收到一个错误&gt;&gt;需要类类型,但发现了Base.this.EntityTable
class LanguageModel(databaseProfile: JdbcProfile) extends Base
{
override val dbProfile: JdbcProfile = databaseProfile
import dbProfile.api._
...
override type EntityTable = LanguageTable
}
存储库本身也没有编译,因为类型不匹配。有多个问题,我不知道从哪里开始解决它们。
答案 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]) {
//...
}
首先编译所有内容,然后开始一次添加一个类。