无法使用Slick更新记录

时间:2013-02-26 14:13:40

标签: scala slick

类和表定义如下所示:

case class Group(
  id: Long = -1,
  id_parent: Long = -1,
  label: String = "",
  description: String = "")

  object Groups extends Table[Group]("GROUPS") {
    def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
    def id_parent = column[Long]("ID_PARENT")
    def label = column[String]("LABEL")
    def description = column[String]("DESC")
    def * = id ~ id_parent ~ label ~ design <> (Group, Group.unapply _)
    def autoInc = id_parent ~ label ~ design returning id into {
      case ((_, _, _), id) => id
    }
  }

要更新记录,我可以这样做:

  def updateGroup(id: Long) = Groups.where(_.id === id)

  def updateGroup(g: Group)(implicit session: Session) = updateGroup(g.id).update(g)

但我无法获得使用for表达式的更新:

  val findGById = for {
    id <- Parameters[Long]
    g <- Groups; if g.id === id
  } yield g

  def updateGroupX(g: Group)(implicit session: Session) = findGById(g.id).update(g)
  ----------------------------------------------------------------------------^
Error: value update is not a member of scala.slick.jdbc.MutatingUnitInvoker[com.exp.Group]

我显然在the documentation.

中遗漏了一些东西

2 个答案:

答案 0 :(得分:7)

update方法由UpdateInvoker类型提供。如果它们在范围内,则可以通过方法Query和/或productQueryToUpdateInvoker(在BasicProfile中找到)从tableQueryToUpdateInvoker隐式创建该类型的实例。 / p>

现在,findById方法的类型不是Query,而是BasicQueryTemplate[Long, Group]。查看文档,我无法找到从BasicQueryTemplateStatementInvoker的子类型)到UpdateInvoker的任何方式,既不是隐式也不是显式。考虑到这一点,这对我来说是有道理的,因为我理解一个查询模板(调用者)是一个已经从抽象语法树(Query)“编译”到相当早的一个准备好的语句的东西参数化,而更新调用程序只能从抽象语法树构建,即Query对象,因为它需要分析查询并提取其参数/列。至少那是它目前的工作方式。

考虑到这一点,可能的解决方案展开:

def findGById(id: Long) = for {
  g <- Groups; if g.id === id
} yield g

def updateGroupX(g: Group)(implicit session: Session) = findGById(g.id).update(g)

其中findById(id: Long)的{​​{1}}类型由Query[Groups, Group]转换为最终可以调用productQueryToUpdateInvoker方法的UpdateInvoker[Group]

希望这会有所帮助。

答案 1 :(得分:4)

请参阅http://madnessoftechnology.blogspot.ru/2013/01/database-record-updates-with-slick-in.html

我坚持今天的更新,这篇博文对我帮助很大。另请参阅帖子下的第一条评论。