我有一个由三个案例类组成的模型,如下所示:
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表映射,如下所示:
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)
}
可以看出,我必须有另一种类型将我的表MyTable首先映射到MyTableElem,然后在每次读取时,我将MyTableElem转换为MyModel。有没有办法避免这种情况并直接进入MyModel?我想我必须实现tupled和unapply方法或?
答案 0 :(得分:1)
我认为您可能需要定义自己的列类型。在Slick 3.0文档Using Custom Scalar Types in Queries中,
您可以使用 MappedTo
。
如果某个支持类型的底层值有一个包装类(可以选择是一个case类和/或一个值类),你可以使它扩展MappedTo以获得一个宏生成的隐式ColumnType。< / p>
以下是我尝试解决问题的方法。
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)
}
无论如何,希望它有所帮助。