在学习游戏技巧和设置最终保存到PostgreSQL的模型类中,我看到了这种模式(下面的代码)。有一个简单的案例类充当模型,然后扩展了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生成表映射,我想从头开始。

最佳答案

对于这个问题的未来搜索者,以下是我发现的内容:

您不能减少样板,它必须在那里。 Slick具有code generation功能,该功能并不完全相同。如果您有一个SQL模式,它将为您生成表映射。

现在,您可能会问,如果它可以自动为您生成表映射,那为什么还要编写它们并维护它们呢?看来答案是这样的,以便可以在编译时加载类型定义。当然,它们可以生成,但是它们不会是“类型安全的”,因为在编译时如果没有实际的代码,编译器就不会针对这些类型检查您的代码。

因此,这似乎取决于在这一层上类型安全性的感知值。如果您认为有必要,那么此代码不是样板。如果您认为在此特定层上的类型安全不是严格必需的,那么这确实是样板。

似乎可以归结为更大的FP假设,即类型安全性始终很重要,这对我来说只是“纯净”论点的结尾。

10-07 15:48