为Slick 3.1.1创建通用更新功能

时间:2016-12-28 07:20:39

标签: scala slick

我有这个功能:

 def updateInvoiceAdminStatusField(id: Int, newAdminStatus: AdminStatus): Future[Int] = {


    db.run {

      val adminStatus: Query[Rep[AdminStatus], AdminStatus, Seq] = InvoicesTable.filter(invoice => invoice.id === id).map(invoice => invoice.status)

      adminStatus.update(newAdminStatus)
    }
  }

我想把它变成通用的:

   def updateInvoiceField[T](id: Int, fieldExtractor: (Invoices) => Rep[T], newValue: T): Future[Int] = {

    db.run {

      val adminStatus = InvoicesTable.filter(invoice => invoice.id === id).map(invoice => {

        fieldExtractor(invoice)
      })

      adminStatus.update(newValue)
    }
  }

但是这不能编译。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:2)

它差不多好。如下所示的小改动应该有效:

// I added below T: ColumnType
def updateInvoiceField[T: ColumnType](id: Int, fieldExtractor: (Invoices) => Rep[T], newValue: T): Future[Int] = {

  db.run {
      val adminStatus = InvoicesTable.filter(invoice => invoice.id === id).map(invoice => {
          fieldExtractor(invoice)
      })

      adminStatus.update(newValue)
  }
}

注意我添加了这个: ColumnType,这基本上意味着你需要在范围内有适当的隐含 - 特别是要转换T =>的那个。 ColumnType[T]。这只是因为否则T可以是任何内容而Slick无法弄清楚如何转换它。

对于StringInt等内容,您显然已经进行了适当的对话(从个人资料/驱动程序中的api导入)。对于自定义类型,您需要使用MappedColumnType来提供正确的转换。以下示例(typesafe ID):

implicit def columnType[T]: BaseColumnType[Id[T]] =
    MappedColumnType.base[Id[T], Long](toLong, fromLong)

private def fromLong[T](dbId: Long): Id[T] = Id(dbId)

private def toLong[T](id: Id[T]): Long = id.value