在学习play-slick,并设置最终保存到PostgreSQL的模型类时,我看到了这种模式(下面的代码)。有一个简单的case类充当模型,然后扩展Table来处理关系映射。
case class Cat(name: String, color: String)
/* Table mapping
*/
class CatsTable(tag: Tag) extends Table[Cat](tag, "CAT") {
def name = column[String]("name", O.PrimaryKey)
def color = column[String]("color", O.NotNull)
def * = (name, color) <> (Cat.tupled, Cat.unapply _)
}
在许多常见的情况下,这让我感到非常不满,但我只是在学习,所以我不知道我在这里缺少什么。是否有一种更简单的方法从case class Cat
开始,最终得到一个可用于数据库中Cat的CRUD实例的对象?例如。似乎没有必要指定String
类型的属性最终应该是column[String]
,依此类推。在其他框架中,我可能需要添加注释或其他内容来指示我想要成为主键,还是不可为空,但我不会真正编写单独的映射。通过手工编写这些映射,我主要是花费更多的时间并有机会以其他简单的情况以微妙的方式搞砸它。
我理想的是从case class Cat
开始,在其上撒上魔法框架灰尘,并获得具有合理默认值的CatsTable
,我可以根据需要覆盖/自定义。
当我在搜索文档时,我通常会回到schema code generation,但这似乎是倒退;我不想从现有/填充RDBMS生成表映射,我想从头开始。
答案 0 :(得分:5)
对于这个问题的未来搜索者,这是我发现的:
你不能减少样板,它必须在那里。 Slick具有code generation功能,但不完全相同;如果你有一个SQL模式,它将为你生成表映射。
现在,您可能会问,如果它可以自动为您生成表映射,为什么还要编写它们并维护它?似乎答案是可以在编译时加载类型定义。当然,它们可以生成,但是它们不会是“类型安全的”,因为编译器不会在没有实际代码的情况下针对这些类型检查代码。
因此,这似乎取决于该层的类型安全感知价值。如果您认为有必要,那么此代码不是样板。如果您认为这个特定层的类型安全性并非严格必要,那么这实际上就是样板。
似乎可以归结为更大的FP假设,类型安全始终是重要的,对我而言,这是一个“纯粹”论点的结尾。