Scala / Play / Squeryl检索多个参数

时间:2016-05-04 15:07:36

标签: scala playframework squeryl

我有以下网址:http://localhost/api/books/?bookId=21&bookId=62?authorId=2

我想用Scala检索所有bookId值,然后使用Squeryl在数据库中进行提取。

我正在使用PlayFrameWork作为WebServer,所以这是我的代码:

val params = request.queryString.map { case (k, v) => k -> v(0) } // Retrieve only one the first occurence of a param

所以 params.get(“bookId”)只会获得bookId参数中的最后一个值。 e-g: 62

要检索我的所有bookId参数,我试过这个:  val params = request.queryString.map { case (k, v) => k -> v }所以我可以得到一个Seq [String],但是authorId不是Seq [String]呢?

最后我想使用Squeryl在我的数据库中获取bookIds和authorId:

(a.author_id === params.get("authorId").?) and
(params.get("bookId").map(bookIds: Seq[String] => b.bookId in bookIds))

在我的控制器中,我得到参数并打开数据库连接:

val params = request.queryString.map { case (k, v) => k -> v(0) }

DB.withTransaction() { where(Library.whereHelper(params)}

在我的模型中,我使用查询:

def whereHelper(params : Map[String,String]) = {

 (a.author_id === params.get("authorId").?) and
 (params.get("bookId").map{bookIds: Seq[String] => b.bookId in bookIds})
}

由于bookIds是一个列表,我需要使用Seq [String]。有一种方法可以使用request.queryString.map {case(k,v)=> k - > v}对于字符串(authorId)和字符串列表(bookIds)?

谢谢,

1 个答案:

答案 0 :(得分:0)

如果我真的明白你想要做什么,你想知道如何从queryString获取参数。这非常简单,您可以在控制器上执行以下操作:

def myAction = Action { request =>
    // get all the values from parameter named bookId and 
    // transforming it to Long. Maybe you don't want the map
    // and then you can just remove it.
    val bookIds: Seq[Long] = request.queryString("bookId").map(_.toLong)

    // Notice that now I'm using getQueryString which is a helper
    // method to access a queryString parameter. It returns an
    // Option[String] which we are mapping to a Option[Long].
    // Again, if you don't need the mapping, just remove it.
    val authorId: Option[Long] = request.getQueryString("authorId").map(_.toLong)

    DB.withTransaction() { where(Library.whereHelper(authorId, bookIds) }

    // Do something with the result
}

在您的模型中,您将拥有:

def whereHelper(authorId: Option[Long], booksId: List[Long]) = authorId match {
  case Some(author_id) =>
      (a.author_id === author_id) and
      (b.bookId in bookIds)
  case None =>
      (b.bookId in bookIds)
}

我已经留下了明确的类型来帮助您了解发生了什么。现在,由于您同时拥有这两个值,因此您只需使用查询中的值即可。

聊天后编辑:

但是,既然您希望在模型中收到params: Map[String, Seq[String]],并且只是遇到如何获取authorId的问题,那么您可以执行以下操作:

def whereHelper(params: Map[String, Seq[String]]) = {
  // Here I'm being defensive to the fact that maybe there is no
  // "booksIds" key at the map. So, if there is not, an Seq.empty
  // will be returned. map method will run only if there is something
  // at the Seq.
  val booksIds = params.getOrElse("booksIds", Seq.empty).map(_.toLong)

  // The same defensive approach is being used here, and also getting
  // the head as an Option, so if the Seq is empty, a None will be 
  // returned. Again, the map will be executed only if the Option
  // is a Some, returning another Some with the value as a Long.
  val authorId = params.getOrElse("authorId", Seq.empty).headOption
  authorId.map(_.toLong) match {
    case Some(author_id) =>
      (a.author_id === author_id) and
      (b.bookId in booksIds)
    case None =>
      (b.bookId in booksIds)
  }
}

当然,你拥有的参数越多,这种方法就越复杂。