在 Scala Slick 中可重用 Table 类

Reusable Table classes in Scala Slick

在 Play 应用程序中,我有几个 table 和 class 共享相同的结构。我想让它们保持不同以维护应用程序语义(是的静态类型!)。但是,我想避免重复样板代码。

例如,这里是 class Region

case class Region(id: Int, name:String)

这里是 Slick 的 table 查询 class:

class RegionsTable(tag:Tag) extends Table[Region](tag, "regions") {
  def id = column[Int]("id", O.AutoInc, O.PrimaryKey)
  def name = column[String]("name", O.Unique)
  
  def * = (id, name) <> (Region.tupled, Region.unapply)
}

如何避免为每个共享 Region 结构的其他 class 重复 table 查询 class?

也许不是很 Slick 的原生解决方案,但重构可能看起来像:

import slick.jdbc.H2Profile.api._
import scala.reflect.ClassTag

case class Region(id: Int, name: String)
case class Country(id: Int, name: String)

class IdNameTable[T](tag: Tag, tableName: String, apply: (Int, String) => T, unapply: T => Option[(Int, String)])
                    (implicit classTag: ClassTag[T]) extends Table[T](tag, tableName) {
  def id = column[Int]("id", O.AutoInc, O.PrimaryKey)
  def name = column[String]("name", O.Unique)
  def * = (id, name) <> (apply.tupled, unapply)
}

class RegionsTable(tag: Tag) extends IdNameTable[Region](tag, "regions", Region, Region.unapply)

class CountryTable(tag: Tag) extends IdNameTable[Country](tag, "country", Country, Country.unapply)

工作 Scatie 示例:https://scastie.scala-lang.org/fR7BzS1jSKSXptE9CTxXyA