Scala Anorm以正确的方式归零

时间:2015-09-08 20:04:58

标签: scala relation anorm

我有一个由2个表组成的简单数据库 - moviecomment,其中评论与电影有关,然后我有以下scala anorm代码:

case class Comment(commentId: Long, comment: String)
case class Movie(movieId: Long, name: String, movieType: String)

object MovieDao {
  val movieParser: RowParser[Movie] = {
    long("movieId") ~
    str("name") ~
    str("movieType") map {
      case movieId ~ name ~ movieType => Movie(movieId, name, movieType)
    }
  }

  val commentParser: RowParser[Comment] = {
    long("commentId") ~
    str("comment") map {
      case commentId ~ comment => Comment(commentId, comment)
    }
  }

  def getAll(movieType: String) = DB.withConnection {
    implicit connection =>
      SQL(
        """
          |SELECT
          |movie.movieId,
          |movie.name,
          |movie.movieType,
          |comment.commentId,
          |comment.comment
          |FROM movie
          |LEFT JOIN comment USING(movieId)
          |WHERE movieType = {movieType}
        """.stripMargin)
      .on("movieType" -> movieType)
      .as(((movieParser ~ (commentParser ?)) map (flatten)) *)
      .groupBy(_._1) map {(mc: (Movie, List[(Movie, Option[Comment])])) =>
        mc match {
          case (a, b) => (a, b filter { //filter rows with no comments
            case (c, Some(d)) => true
            case _ => false
          } map(_._2))
        }
      } toList
  }
}

我的目标是从List[(Movie, Option[List[Comment]])]方法返回getAll,这样我就可以迭代电影并检查是否有任何评论尽可能简单,e.i。匹配评论列表中的无或部分。我目前正在返回List[(Movie, Option[List[Option[Comment]])]并且我只能检查注释列表的大小(感谢使用filter方法),我不认为这是在scala中执行此操作的正确方法。

我的第二个问题是关于解析查询本身,我认为这只是复杂化我的方式。有没有更简单,更好的解决方案来解析使用anorm的0..N关系?

1 个答案:

答案 0 :(得分:1)

彼得,它的风格可能比任何显着不同的东西都要多,但是对于case class MovieComments(movie: Movie, comments: List[Comment]) val movieCommentsP = movieParser ~ (commentParser ?) map { case movie ~ comment => MovieComments(movie,if (comment.isEmpty) List() else List(comment.get)) } val movieSqlSelector = "m.movieId, m.name, m.movieType" val commentSqlSelector = "c.commentId, c.comment" def getAll(movieType: String) :List[MovieComments]= DB.withConnection { implicit connection => (SQL( s""" |SELECT |$movieSqlSelector, |$commentSqlSelector |FROM movie |LEFT JOIN comment USING(movieId) |WHERE movieType = {movieType} """.stripMargin) .on('movieType -> movieType) .as(movieCommentsP *) .groupBy(_.movie.movieId) map { case (movieId,movieComments) => MovieComments( movieComments.head.movie, movieComments.flatMap(_.comments)) } ).toList } 案例类,你可以写下这样的东西:

Option[List[Comment]]

您可能真的需要List[Comment],但不会List()吗? sqlSelector是"没有评论"毕竟是个案。 (P.S.我发现使用[NSLayoutConstraint constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:]: A multiplier of 0 or a nil second item together with a location for the first attribute creates an illegal constraint of a location equal to a constant. Location attributes must be specified in pairs' 变量有助于重构。)