我正在使用Play Framework和Squeryl为数据库创建一个相当基本的前端,但我知道我正在重写太多的代码。我有不同的模型来表示我的数据库中的数据,它们都执行相同的六个函数
object ModelType{
def add(model:ModelType):Option[ModelType] = Option(AppDB.tablename.insert(model))
def remove(id: Long) = AppDB.tablename.delete(id)
def getAll():List[ModelType] = from(AppDB.tablename)(model => select(model) orderBy(model.aDifferentFieldForEachModel)) toList
def toJson(model:ModelType):JsValue ={
Json.toJson(
Map("field" -> Json.toJson(model.field))
)
}
def allToJson() = {
val json:List[JsValue] = getAll.map{toJson(_)}
Json.toJson(json.toSeq)
}
def validate(different values for each model) = // is fairly different for each one. Validates the submitted fields from a user
}
所以我正在为每个模型使用case类,并使用附带的对象来执行这些命令。如何在scala中使用泛型或特征来使我的生活更轻松,而不是每次都输入所有这些方法?
编辑:主要用gzm0的答案解决了,但现在的问题是如何在特性中实现getAll?我希望能够为每个类似于model.aDifferentFieldForEachModel
的模型保存一些变量。
答案 0 :(得分:2)
您可以尝试以下方法:
trait ModelOps[T] {
def table: AppDB.Table // not sure about type
def order: AppDB.OrderByPredicate // not sure about type
def toJson(model: T): JsValue
def add(model: T): Option[T] = Option(AppDB.categories.insert(model))
def remove(id: Long) = AppDB.categories.delete(id)
def getAll(): List[T] = from(table)(model => select(model) orderBy(order)) toList
def allToJson() = {
val json:List[JsValue] = getAll.map{toJson(_)}
Json.toJson(json.toSeq)
}
}
然后您可以为每种模型类型:
object ModelType extends ModelOps[ModelType] {
def table = AppDB.examples
def order = yourPredicate
def toJson(model:ModelType):JsValue = {
Json.toJson(Map("field" -> Json.toJson(model.field)))
}
def validate(different values for each model) = // is fairly different for each one. Validates the submitted fields from a user
}
更新关于AppDB.OrderByPredicate
的真实类型:
在PrimitiveTypeMode
上呼叫select
会返回SelectState
。在此SelectState
上,您将调用orderBy
,其中List[BaseQueryYield#O]
(或同一参数列表中的多个)。因此,您应该定义:
def order(model: T): List[BaseQueryYield#O]
和
def getAll() = from(table)(model => select(model) orderBy(order(model))) toList
顺便说一下,BaseQueryYield#O
会解析为ExpressionNode
。