У меня есть простая база данных, состоящая из 2-х таблиц - movie
и comment
, где комментарии, связанные с кино, а потом я следующий кусок Scala anorm код: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
, поэтому я могу перебирать фильмы и проверять, есть ли какие-либо комментарии как можно более простые, ei соответствие None или Some в списке комментариев. Я в настоящее время возвращаю List[(Movie, Option[List[Option[Comment]])]
, и я могу только проверить размер списка комментариев (спасибо, используя метод filter
), который я не считаю правильным способом сделать это в scala.
Мой второй вопрос заключается в анализе самого запроса, я думаю, что это просто сложно, как я это сделал. Есть ли более простое и приятное решение для разбора отношения 0..N с использованием анорма?
У Anorm нет способа разбора отношений «один ко многим». Я сделал аналогичную вещь в [этом ответе] (http://stackoverflow.com/questions/24315202/flatten-a-list-of-anorm-tuples/24315461#24315461). В конечном итоге я написал [anorm-relational] (https://github.com/mhzajac/anorm-relational), чтобы сократить часть дублирования кода, вызванного этим. (Отказ от ответственности: я являюсь автором этой библиотеки, и она начинает показывать возраст) –