简体   繁体   English

播放Scala Anorm动态SQL进行UPDATE查询

[英]Play Scala Anorm dynamic SQL for UPDATE query

My Google-fu is letting me down, so I'm hoping you can help 我的Google-fu令我失望,希望您能为您提供帮助

I'm building some webservices is the play framework using scala and anorm for database access 我正在构建一些网络服务,这是使用scala和anorm进行数据库访问的播放框架

One of my calls is to update an existing row in a database - ie run a query like 我的电话之一是更新数据库中的现有行-即运行查询

UPDATE [Clerks]
   SET [firstName] = {firstName}
  ,[lastName] = {lastName}
  ,[login] = {login}
  ,[password] = {password}
 WHERE [id] = {id}

My method receives a clerk object BUT all the parameters are optional (except the id of course) as they may only wish to update a single column of the row like so 我的方法收到一个店员对象,但所有参数都是可选的(当然,id除外),因为它们可能只希望更新行的单个列,如下所示

UPDATE [Clerks]
   SET [firstName] = {firstName}
 WHERE [id] = {id}

So I want the method to check which clerk params are defined and build the 'SET' part of the update statement accordingly 因此,我希望该方法检查定义了哪些业务员参数,并相应地构建更新语句的“ SET”部分

It seems like there should be a better way than to go through each param of the clerk object, check if it is defined and build the query string - but I've been unable to find anything on the topic so far. 似乎比遍历业务对象的每个参数,检查是否已定义并构建查询字符串,还有更好的方法-但到目前为止,我在该主题上找不到任何东西。

Does anyone have any suggestions how this is best handled 有谁有任何建议如何最好地处理

As the commenters mentioned it appears to not be possible - you must build the query string yourself. 正如评论者提到的那样,这似乎是不可能的-您必须自己构建查询字符串。

I found that examples around this lacking and it took more time to resolve this than it should have (I'm new to scala and the play framework, so this has been a common theme) 我发现缺少解决此问题的示例,解决该问题所需的时间超过了应有的时间(我对scala和play框架是陌生的,因此这是一个常见的主题)

in the end this is what I implemented: 最后,这是我实现的:

override def updateClerk(clerk: Clerk) = {
  var setString: String = "[modified] = {modified}"
  var params: collection.mutable.Seq[NamedParameter] = 
     collection.mutable.Seq(
            NamedParameter("modified", toParameterValue(System.currentTimeMillis / 1000)), 
            NamedParameter("id", toParameterValue(clerk.id.get)))

  if (clerk.firstName.isDefined) {
    setString += ", [firstName] = {firstName}"
    params = params :+ NamedParameter("firstName", toParameterValue(clerk.firstName.getOrElse("")))
  }
  if (clerk.lastName.isDefined) {
    setString += ", [lastName] = {lastName}"
    params = params :+ NamedParameter("lastName", toParameterValue(clerk.lastName.getOrElse("")))
  }
  if (clerk.login.isDefined) {
    setString += ", [login] = {login}"
    params = params :+ NamedParameter("login", toParameterValue(clerk.login.getOrElse("")))
  }
  if (clerk.password.isDefined) {
    setString += ", [password] = {password}"
    params = params :+ NamedParameter("password", toParameterValue(clerk.password.getOrElse("")))
  }
  if (clerk.supervisor.isDefined) {
    setString += ", [isSupervisor] = {supervisor}"
    params = params :+ NamedParameter("supervisor", toParameterValue(clerk.supervisor.getOrElse(false)))
  }

  val result = DB.withConnection { implicit c =>
    SQL("UPDATE [Clerks] SET " + setString + " WHERE [id] = {id}").on(params:_*).executeUpdate()
  }
}

it likely isn't the best way to do this, however I found it quite readable and the parameters are properly handled in the prepared statement. 这样做可能不是最好的方法,但是我发现它很易读,并且在准备好的语句中可以正确处理参数。

Hopefully this can benefit someone running into a similar issue 希望这可以使遇到类似问题的人受益

If anyone wants to offer up improvements, they'd be gratefully received 如果有人想提供改进,将不胜感激

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM