Slick 3.0.0 映射现有模型

Slick 3.0.0 Mapping Existing Models

我有一个由三种情况 类 组成的模型,如下所示:

case class MyModel(myId: MyIdType, name: MyNameType)

case class MyIdType(id: Long)
case class MyNameType(name: String)
object MyNameType(name: String) {
  val NAME1 = MyNameType("name1")
  val NAME2 = MyNameType("name2")
  val NAME3 = MyNameType("name3")
}

假设这些是现有模型。我有一个像这样的 Slick table 映射:

  class MyTable(tag: Tag) extends Table[MyTableElem](tag, "myTable") {
    def id                  = column[Long]("id", O.PrimaryKey)
    def name                = column[String]("name")

    def * = (id, name) <> (MyTableElem.tupled, MyTableElem.unapply)
  }

可以看出,我必须有另一种类型才能将我的 table MyTable 首先映射到 MyTableElem,然后在每次读取期间,我将 MyTableElem 转换为 MyModel。有没有办法避免这种情况并直接转到 MyModel?我想我必须实现 tupled 和 unapply 方法或者?

我认为您可能必须定义自己的列类型。在 Slick 3.0 文档中 Using Custom Scalar Types in QueriesMappedTo 可用于您的情况。

If you have a wrapper class (which can optionally be a case class and/or value class) for an underlying value of some supported type, you can make it extend MappedTo to get a macro-generated implicit ColumnType for free.

以下是我如何尝试解决您的问题。

import slick.lifted.Tag
// I am using PostgreSQL
import slick.driver.PostgresDriver.api._

case class MyModel(myId: MyIdType, name: MyNameType)

case class MyIdType(id: Long) extends MappedTo[Long] {
  override def value: Long = id
}
case class MyNameType(name: String) extends MappedTo[String] {
  override def value: String = name
}

class MyTable(tag: Tag) extends Table[MyModel](tag, "myTable") {
  def id                  = column[MyIdType]("id", O.PrimaryKey)
  def name                = column[MyNameType]("name")

  def * = (id, name) <> (MyModel.tupled, MyModel.unapply)
}

无论如何,希望对您有所帮助。