我一直在使用Play framework 2.0大约6个月,我一直想知道为什么他们使用这么多的样板代码来解析我的SQL查询返回,如下所示:
case class Journal_accountDetail(amount: Double, states: Boolean)
val Journal_AccountParser: RowParser[Journal_accountDetail] = {
get[Double] ("amount") ~
get[Boolean] ("states") map({
case amount~states => Journal_accountDetail(amount,states)
})
}
Run Code Online (Sandbox Code Playgroud)
是否能够提升Play框架的性能?
Mic*_*jac 11
解析API可以在开始可能会有点乏味,但它是相当强大的,当你开始合并和重新使用的解析器,并且很多不是在每个返回一个SQL结果函数模式匹配不太难看.
想象一下这样的事情:
case class User(id: Int, name: String, address: Address)
case class Address(id: Int, street: String, city: String, state: State, country: Country)
case class State(id: Int, abbrev: String, name: String)
case class Country(id: Int, code: String, name: String)
Run Code Online (Sandbox Code Playgroud)
构造User你需要用多个JOINs 解析一个结果.我们不是拥有一个大的解析器,而是为它的伴随对象中的每个类构造一个:
object User {
val parser: RowParser[User] = {
get[Int]("users.id") ~
get[String]("users.name") ~
Address.parser map {
case id~name~address => User(id, name, address)
}
}
}
object Address {
val parser: RowParser[Address] = {
get[Int]("address.id") ~
get[String]("address.street) ~
get[String]("address.city") ~
State.parser ~
Country.parser map {
case id~street~city~state~country => Address(id, street, city, state, country)
}
}
}
object State {
val parser: RowParser[State] = {
get[Int]("states.id") ~
get[String]("states.abbrev") ~
get[String]("states.name") map {
case id~abbrev~name => State(id, abbrev, name)
}
}
}
object Country {
val parser: RowParser[Country] = {
get[Int]("countries.id") ~
get[String]("countries.code") ~
get[String]("countries.name") map {
case id~code~name => Country(id, code, name)
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意我如何在解析器中使用完整的表空间,以避免列名冲突.
总而言之,这看起来像很多代码,但对于每个源文件来说,它只占很小的空间.最大的好处是我们的User解析器非常干净,尽管它的结构很复杂.比方说,在User该address实际上是Option[Address].然后考虑到这种变化就像Address.parser在User解析器中更改一样简单(Address.parser ?).
对于解析简单查询,是的,它确实看起来像很多样板.但是我非常感谢解析API解析上面的例子(以及更复杂的例子).