我有这些案例类:
case class PolicyHolder(id : String, firstName : String, lastName : String)
case class Policy(address : Future[Address], policyHolder : Future[PolicyHolder], created : RichDateTime, duration : RichDuration )
Run Code Online (Sandbox Code Playgroud)
然后我为Policy定义了一个光滑的模式
class PolicyDAO(tag: Tag) extends Table[Policy](tag, "POLICIES") with DbConfig {
def address = column[String]("ADDRESS", O.PrimaryKey)
def policyHolder = foreignKey("POLICY_HOLDER_FK", address, TableQuery[PolicyHolderDAO])(_.id)
def created = column[RichDateTime]("CREATED")
def duration = column[String]("DURATION")
def * = (address, policyHolder, created, duration) <> (Policy.apply, Policy.unapply)
}
Run Code Online (Sandbox Code Playgroud)
对我来说,正确定义此投影以将policyHolder
我的Policy
case类中的字段从外键值映射到case类的实际实例的最佳方法是什么PolicyHolder
.
我们对此问题的解决方案是将外键 id 放入 case 类中,然后使用惰性 val 或 def(后者可能由缓存支持)来使用该键检索记录。这是假设你的PolicyHolder
s 存储在一个单独的表中 - 如果它们是非规范化的,但你想将它们视为单独的案例类,那么你可以使用惰性 val / def 构造Policy
一个新的案例类,而不是使用外键。
class PolicyDAO(tag: Tag) extends Table[Policy](tag, "POLICIES") with DbConfig {
def address = column[String]("ADDRESS", O.PrimaryKey)
def policyHolderId = column[String]("POLICY_HOLDER_ID")
def created = column[RichDateTime]("CREATED")
def duration = column[String]("DURATION")
def * = (address, policyHolderId, created, duration) <> (Policy.apply, Policy.unapply)
}
case class Policy(address : Future[Address], policyHolderId : Future[String], created : RichDateTime, duration : RichDuration ) {
lazy val policyHolder = policyHolderId.map(id => PolicyHolderDAO.get(id))
}
Run Code Online (Sandbox Code Playgroud)
我们还使用了一组通用的创建/更新/删除方法来解释嵌套,这样当 aPolicy
被提交时,它的内部PolicyHolder
也会被提交;我们使用了一个CommonDAO
扩展的类Table
,并具有创建/更新/删除方法的原型,然后所有 DAO 都CommonDAO
根据Table
需要扩展而不是覆盖创建/更新/删除。
编辑:为了减少错误并减少我们必须编写的样板文件数量,我们使用了 Slick 的代码生成工具- 这样可以从模式自动生成 CRUD 操作