简单的光滑插入/获取的最佳实践是什么?



我需要将Slick 3.1.1用于基于Postgres的项目,但我很难为以下超简单的用法编写干净的代码:

假设我有一个Task模型:

case class Task(id: Option[UUID], foo: Int, bar: String)

id: UUID是主键,所以在执行数据库INSERT时不应该提供它(id = None)。但是,在执行将数据库行映射到Task对象的GET时,我确实需要它。

因此,Slick Table类变得非常丑陋:

class Tasks(tag: Tag) extends Table[Task](tag, "tasks") {
def id = column[UUID]("id", O.SqlType("UUID"), O.PrimaryKey)
def foo = column[Int]("foo")
def bar = column[String]("bar")
def insert: MappedProjection[Task, (Int, String)] =
(foo, bar).shaped.<>(
{ tuple =>
Task.tupled(None, tuple._1, tuple._2)
}, { (task: Task) =>
Task.unapply(task).map { tuple =>
(tuple._2, tuple._3)
}
}
)
override def * : ProvenShape[Task] =
(id.?,
foo,
bar).shaped.<>(Task.tupled, Task.unapply)
}

如果案例类Task有10个元素,那么我就必须写(tuple._1, tuple._2, tuple._3, ......)。如果我提交如上所述的PR,我的同事会扇我耳光。请建议!

如果让数据库自动增加您的ID,则表定义可能会显著缩短:

import slick.driver.PostgresDriver.api._
import java.util.UUID
case class Task(id: Option[UUID], foo: Int, bar: String)
class Tasks(tag: Tag) extends Table[Task](tag, "tasks") {
def id = column[Option[UUID]]("id", O.SqlType("UUID"), O.PrimaryKey, O.AutoInc)
def foo = column[Int]("foo")
def bar = column[String]("bar")
def * = (id, foo, bar) <> (Task.tupled, Task.unapply)
}

这可以通过将id字段移动到case类的末尾并为其提供默认的None值来进一步改进。这样,您就不必在每次想要实例化Task:时都提供它

case class Task(foo: Int, bar: String, id: Option[UUID] = None)
val firstTask = Task(123, "John")
val secondTask = Task(456, "Paul")

相关内容

最新更新