Scala 使用anorm时如何组织play framework 2的实体模型

Scala 使用anorm时如何组织play framework 2的实体模型,scala,playframework-2.0,anorm,Scala,Playframework 2.0,Anorm,我有一个带有一组字段和外键的表 使用Ebean时,我可以指定填写请求的字段,仅从以外部关系结尾的id开始(并不总是需要将数据库中的所有字段都包含在类中)。它只使用一个绑定到表的类 @Entity public class Product extends Model{ @Id public Long id; @Constraints.Required public String name; @Lob public String description; @ManyToOne publ

我有一个带有一组字段和外键的表

使用Ebean时,我可以指定填写请求的字段,仅从以外部关系结尾的id开始(并不总是需要将数据库中的所有字段都包含在类中)。它只使用一个绑定到表的类

@Entity
public class Product extends Model{   

@Id
public Long id;

@Constraints.Required
public String name;

@Lob
public String description;

@ManyToOne
public Trademark trademark;

...

}
Q1。在使用Anorm时,鼓励使用
案例类
,但我需要指定
案例类
的所有可能字段并填充它们。如果我只需要一个带有
Id
Name
字段的对象,或者只需要带有
Id
字段的ref对象?我必须描述另一个班级

case class ProductRef (id: Pk[Long] = NotAssigned)
case class Product (id: Pk[Long] = NotAssigned, name: String)
case class ProductWithTrademark (id: Pk[Long] = NotAssigned, name: String, trademark: Trademark)
...
case class Trademark (id: Pk[Long] = NotAssigned, name: String ="")
Q2。如果可以将此表用作另一个表中的外键,该怎么办?要使用哪个
案例类

case class Size(id: Pk[Long] = NotAssigned, name: String)
case class ProductSize(id: Pk[Long] = NotAssigned, product: ??? , size: Size)
Q3。或者最好总是用默认值填充所有字段,并且只使用一个
case类

case class Product(id: Pk[Long] = NotAssigned, name: String="", trademark: Trademark = Trademark())
case class Trademark(id: Pk[Long] = NotAssigned, name: String="")
case class Size(id: Pk[Long] = NotAssigned, name: String = "")
case class ProductSize(id: Pk[Long] = NotAssigned, product: Product = Product(), size: Size = Size())

Q4。或者有一个正确的决定,关于哪个我根本不知道

当表中有几个字段可以为空时,通常的做法是将它们设置为case类中的选项。例如,与其拥有:

case class Product (id: Pk[Long] = NotAssigned, name: String)
case class ProductWithTrademark (id: Pk[Long] = NotAssigned, name: String, trademark: Trademark)
你应该:

case class Product (id: Pk[Long] = NotAssigned, name: String, trademark: Option[Trademark])
然后将产品解析器设置为检查
商标是否存在


Play附带的计算机数据库示例描述了完全相同的情况。在该示例中,他们使用以下案例类来描述其模型:

case class Company(id: Pk[Long] = NotAssigned, name: String)
case class Computer(id: Pk[Long] = NotAssigned, name: String, introduced: Option[Date], discontinued: Option[Date], companyId: Option[Long])
您可以看到外键被设置为
选项
,因为a
计算机
型号可以(没有)链接到它的
公司
计算机
解析器描述如下:

val simple = {
    get[Pk[Long]]("computer.id") ~
    get[String]("computer.name") ~
    get[Option[Date]]("computer.introduced") ~
    get[Option[Date]]("computer.discontinued") ~
    get[Option[Long]]("computer.company_id") map {
      case id~name~introduced~discontinued~companyId => Computer(id, name, introduced, discontinued, companyId)
    }
}
请注意在解析外键时如何使用
get[Option[Long]]
。 公司解析器是以相同的方式定义的,当想要同时获取
计算机
公司
(如果设置了外键
公司id
),他们使用以下解析器返回元组
(计算机,选项[company])


也许我无法描述我想要什么。当然,数据库的
nullable
字段在应用程序中必须是
可选的
,但是我的问题是,当只从数据库读取id+name(例如,如果部分代码只需要它们)时,在不填充所有字段的情况下使用
case class
,或者创建新的case类,或者如上所述将所有字段作为选项。使用两种解决方案怎么样?使用默认值为
None的
选项
?实际上,如果字段为空,上述解析器将自动返回None。现在,没有什么可以阻止您在默认情况下将它们设置为null,因为有时您需要创建一个case类并对其进行处理,或者只是在将相应的信息插入数据库之前。所以,是的,你可以同时做这两件事<默认情况下,
案例类
中的code>null
,数据库可空值的
选项
。如果在数据库中存储了
null
parser,则将
None
放在
case类
字段中
val withCompany = Computer.simple ~ (Company.simple ?) map {
    case computer~company => (computer,company)
}