在Anorm中,可以将多个ColumnAliaser应用于同一查询

时间:2016-07-27 20:34:34

标签: scala anorm

该方案类似于How to better parse the same table twice with Anorm?处的问题,但无法再使用所述解决方案。

在Message有2个用户的场景中,我需要使用SQL连接解析from_user和to_user。

case class User(id: Long, name: String)

case class Message(id: Long, body: String, to: User, from: User)

def userParser(alias: String): RowParser[User] = {
    get[Long](alias + "_id") ~ get[String](alias + "_name") map {
        case id~name => User(id, name)
    }
}

val parser: RowParser[Message] = {
    userParser("from_user") ~
    userParser("to_user") ~
    get[Long]("messages.id") ~ 
    get[String]("messages.name") map {
        case from~to~id~body => Message(id, body, to, from)
    }
}

// More alias here possible ?
val aliaser: ColumnAliaser = ColumnAliaser.withPattern((0 to 2).toSet, "from_user.")

SQL"""
SELECT from_user.* , to_user.*, message.* FROM MESSAGE
JOIN USER from_user on from_user.id = message_from_user_id
JOIN USER to_user on to_user.id = message.to_user
"""
.asTry(parser, aliaser)

1 个答案:

答案 0 :(得分:3)

如果我认为你想要将多个ColumnAliaser使用不同的别名政策应用于同一个查询,那么了解ColumnAliaser是“只是”一个specific implementation of Function[(Int, ColumnName), Option[String]]是很正确的,所以它可以定义/组成任何Function,并由companion object中的工厂函数简化。

import anorm.{ ColumnAliaser, ColumnName }

val aliaser = new ColumnAliaser {
  def as1 = ColumnAliaser.withPattern((0 to 2).toSet, "from_user.")
  def as2 = ColumnAliaser.withPattern((2 to 4).toSet, "to_user.")

  def apply(column: (Int, ColumnName)): Option[String] =
    as1(column).orElse(as2(column))
}