假设我有以下两个类:
case class User(id: Long, name: String)
case class Message(id: Long, body: String, to: User, from: User)
RowParser
可能看起来像这样:
val parser: RowParser[User] = {
get[Long]("users.id") ~ get[String]("users.name") map {
case id~name => User(id, name)
}
}
val parser: RowParser[Message] = {
get[Long]("messages.id") ~
get[String]("messages.name") ~
User.parser ~
User.parser map {
case id~body~to~from => Message(id, body, to, from)
}
}
除非这不起作用,因为在加入users
表两次时,Anorm只会解析第一个连接的列(两次),因此to
和from
会是一样的。
可以使用User
解析器中的列别名来解决这个问题:
def parser(alias: String): RowParser[User] = {
getAliased[Long](alias + "_id") ~ getAliased[String](alias + "_name") map {
case id~name => User(id, name)
}
}
然后在User
解析器中为每个Message
使用不同的别名:
val parser: RowParser[Message] = {
get[Long]("messages.id") ~
get[String]("messages.name") ~
User.parser("to") ~
User.parser("from") map {
case id~body~to~from => Message(id, body, to, from)
}
}
这对于简单的方案是可以的,但如果User
更复杂并且Address
包含State
和Country
等,该怎么办?这将需要别名多个表和解析器,这会非常混乱。
有没有更好的方法来实现这一目标?也就是说,我希望在一个查询中选择所有相关数据,并使用解析器组合器解析它,而不需要大量的列别名方案。