在使用anorm时如何组织play框架2的实体模型

时间:2014-03-16 08:13:16

标签: 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
public Trademark trademark;

...

}

Q1 即可。在与Anorm合作时鼓励使用case class,但我需要指定case class的所有可能字段并填充它们。如果我只需要一个包含字段IdName的对象,或只需要一个带有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可以使用?

case class Size(id: Pk[Long] = NotAssigned, name: String)
case class ProductSize(id: Pk[Long] = NotAssigned, product: ??? , size: Size)

Q3 即可。或者最好总是用默认值填充所有字段,并且只使用一个case class

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 即可。或者有正确的决定我根本不知道

1 个答案:

答案 0 :(得分:2)

通常的做法是,在表中有几个可以为null的字段是在case类中将它们设置为Option。例如,而不是:

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])

然后设置您的产品解析器以检查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])

您可以看到外键设置为Option,因为Computer模型可以(没有)链接到Company。 然后,Computer解析器描述如下:

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]]。 公司解析器以相同的方式定义,并且当想要同时获得ComputerCompany时(如果设置了外键company_id),他们使用以下解析器返回元组(Computer,Option[Company])

val withCompany = Computer.simple ~ (Company.simple ?) map {
    case computer~company => (computer,company)
}