问题描述
我对Scala并不陌生,尝试学习 slick ,并从play-slick-example开始,一切都可以理解。
我开始创建自己的实体,表和查询。
第一个技巧是解决在插入时获得自动递增的id的问题,但是示例代码可以解决这个问题,尽管习惯用法可能有所改进。
解决的下一件事是将所有通用代码移到一个位置。通用代码是指基本的CRUD操作,基本上对所有实体都进行复制粘贴。
于是我去创建了基础Entity
trait Entity[T <: Entity[T,ID],ID] {
val id: Option[ID]
def withId(id: ID): T
}
接下来,我创建了BaseRepo
,其中应包含所有通用代码:
abstract class BaseRepo[T <: Entity[T,ID] {
protected val dbConfigProvider: DatabaseConfigProvider
val dbConfig = dbConfigProvider.get[JdbcProfile]
import dbConfig._
import profile.api._
type TableType <: Keyed[ID] with RelationalProfile#Table[T]
protected val tableQuery: TableQuery[TableType]
}
将dbConfigProvider
注入到实现中,并允许导入正确的配置(不确定是否需要它,但是示例具有这样的含义)。 Keyed
是另一个特征,它用列Table
表示id
:
trait Keyed[ID] {
def id: Rep[ID]
}
目前看来一切都很好。要扩展BaseRepo
,将需要适当地分配TableType
和tableQuery
,并且一切正常。
我从以下实现开始:
case class Vehicle(override val id: Option[Long],name: String,plate: String,modelId: Long)
extends Entity[Vehicle,Long] {
override def withId(id: Long): Vehicle = this.copy(id = Some(id))
}
以及以下回购:
@Singleton
class VehicleRepository @Inject()(override val dbConfigProvider: DatabaseConfigProvider)
(implicit ec: ExecutionContext)
extends BaseRepo [Vehicle,Long]{
import dbConfig._
import profile.api._
type TableType = Vehicles
val tableQuery = TableQuery[Vehicles]
class Vehicles(tag:Tag) extends Table[Vehicle](tag:Tag,"vehicles") with Keyed[Long] {
def id = column[Long]("id",O.PrimaryKey,O.AutoInc)
def name = column[String]("name")
def plate = column[String]("plate")
def modelId = column[Long]("modelId")
def * = (id.?,name,plate,modelId) <> ((Vehicle.apply _).tupled,Vehicle.unapply)
}
一切仍然看起来不错!
现在,我将all()
添加到BaseRepo:
def all() = db.run {
tableQuery.result
}
它有效!我可以使用简单的Vehicle
通过注入的repo:VehicleRepository
列出我所有的repo.all()
实体(好吧,我确切地说是Future
,但谁在乎)
接下来,我去尝试使用自动递增的ID概括化插入,并将其放入BaseRepo
:
def create(item: T,ec:ExecutionContext) = db.run{
((tableQuery returning tableQuery.map(_.id)) += item)
.map(id => item.withId(id))(ec)
}
在这里不要介意ExecutionContext
,但是无论如何,这是行不通的,并且错误让我很沮丧:
Slick does not kNow how to map the given types.
Possible causes: T in Table[T] does not match your * projection,you use an unsupported type in a Query (e.g. scala List),or you forgot to import a driver api into scope.
required level: slick.lifted.FlatShapeLevel
Source type: slick.lifted.Rep[ID]
Unpacked type: T
Packed type: G
]
如果我将此方法移回到VehicleRepository
中(用T
代替Vehicle
,则一切都像是一种魅力。
经过数小时的挖掘,我了解到tableQuery.map
使用一些(implicit shape: Shape[_ <: FlatShapeLevel,F,T,G])
作为隐式参数,而我实际上不知道VehicleRepository
的范围是哪里来的,为什么呢?在我的BaseRepo
任何有关如何解决此问题的建议或建议,或者其他一些使用Slick概括CRUD的方法,都将适用!
我正在使用Play-2.8 Slick-3.3.2 play-slick-5.0.0 scala-2.13.1
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)