如何使用映射投影 * <>

How to use the mapped projection * <>

在 slick 你写了一个 projection 那:

defines how the columns are converted to and from the Person object.

默认格式为:

def * = (id, name, age) <> ((Person.apply _).tupled, Person.unapply)

我们可以用它直接map classes/tuples到数据库表。
作为转换的一部分,您可以使用它来更改值吗?

例如纯粹作为一个例子,你可以在 Person 对象中设置一个常量值,但在数据库中忽略它吗?或者将名称映射为数据库中的字符串,并映射为 Person 对象中的枚举?

编译以下代码

import slick.jdbc.PostgresProfile.api._

trait Name
object Name {
  case class Ordinary(s: String) extends Name
  case class Manager(s: String) extends Name
  case object NoName extends Name
}

case class Person(id: Long, name: Name, age: Int, isValid: Boolean)

class Persons(tag: Tag) extends Table[Person](tag, "persons") {
  def id = column[Long]("id", O.PrimaryKey)
  def name = column[String]("name")
  def age = column[Int]("age")

  def * = (id, name, age) <> ({
    case (l, "NoName", i)                  => Person(l, Name.NoName, i, true)
    case (l, s, i) if s.startsWith("Mgr.") => Person(l, Name.Manager(s.stripPrefix("Mgr.")), i, true)
    case (l, s, i)                         => Person(l, Name.Ordinary(s), i, true)
  }, (p: Person) => p.name match {
    case Name.Ordinary(s) => Some((p.id, s, p.age))
    case Name.Manager(s)  => Some((p.id, "Mgr." + s, p.age))
    case Name.NoName      => Some((p.id, "NoName", p.age))
  })
}

这里我们设置isValid为常量值,并将name映射到枚举。