如何使用映射投影 * <>
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
映射到枚举。
在 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
映射到枚举。