加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何在Scala Slick中运行补丁/部分数据库UPDATE?

发布时间:2020-12-16 09:21:45 所属栏目:安全 来源:网络整理
导读:我们想用Slick(3.0.0)运行补丁/部分UPDATE,以便我们只修改记录中的一些字段.完全正确更新哪些字段将只在运行时被知道. 例如,对于REST PATCH request. 目前,我们首先运行SELECT以获取原始记录,然后运行UPDATE,但在单个SQL语句中执行此操作更为可取. 这样的事
我们想用Slick(3.0.0)运行补丁/部分UPDATE,以便我们只修改记录中的一些字段.完全正确更新哪些字段将只在运行时被知道.

例如,对于REST PATCH request.

目前,我们首先运行SELECT以获取原始记录,然后运行UPDATE,但在单个SQL语句中执行此操作更为可取.

这样的事情

def patchPerson(name: Option[String],age: Option[Int]) = {
   people.filter(_.name === "M Odersky")
       .map(p => 
           (name,age) match {
              case (Some(_),Some(_)) => (p.name,p.age)
              case (Some(_),None)    => (p.name)
              case (None,Some(_)) => (p.age)
           }
       )
       .update(
           (name,Some(_)) => (name.get,age.get)
              case (Some(_),None)    => (name.get)
              case (None,Some(_)) => (age.get)
           }
       )
}

(请忽略这里的丑陋代码)

以上不会使用以下错误消息进行编译:

No matching Shape found. Slick does not know how to map the given
types. Possible causes: T in Table[T] does not match your *
projection. Or you use an unsupported type in a Query (e.g. scala
List). Required level: slick.lifted.FlatShapeLevel Source type:
Object Unpacked type: T Packed type: G

和:

not enough arguments for method map: (implicit shape:
slick.lifted.Shape[_ <: slick.lifted.FlatShapeLevel,Object,T,
G])slick.lifted.Query[G,Seq]. Unspecified value parameter shape.

我假设这是因为Slick期望元组长度和类型与过滤器和更新功能的结果相匹配.

我们尝试使用Slick heterogeneous list课程,但这似乎也期望长度和类型匹配.

有没有办法在Slick中写这个,以便我们可以用一个数据库调用来更新记录中任意数量的字段?

解决方法

我最好的猜测是运行一个 plain SQL query

即使SQL查询有两个部分,关系数据库管理系统(postgresql,mysql等)也可以调用查询.

我不知道在这种情况下,Slick是否能够优化,但在几种情况下,它也是optimizes the queries本身.

典型更新:

def updateRecord(id: Long,field1: Int) = {
    db.withSession {
      self.filter(_.id === id).map(_.field1).update(field1)
    }
}

做你的更新类型需要像你这样的逻辑.不要以为只有在运行时才知道要更改的字段才可以简化.但您可以强制更新,使用记录上的字段的现有值作为备用(可能导致DB上的更新更多)

def updateRecord(id: Long,field1: Option[Int],field2: Option[Int]) = {
    db.withSession {
        self.filter(_.id === id).map(_.field1,_.field2).update(field1.getOrElse(existingValue1),field2.getOrElse(existingValue2)) 
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读