简体   繁体   English

在PostgreSQL 9.0中断开的Anorm选择Order By?

[英]Anorm broken in PostgreSQL 9.0 Selects with Order By?

I'm trying to build a list page like the one in the "Computers" sample. 我正在尝试构建一个类似“计算机”示例中的列表页面。 My environment is Play 2.0 and PostrgreSQL 9.0 我的环境是Play 2.0和PostrgreSQL 9.0

I have the following method in my User object: 我的User对象中有以下方法:

 def list(page: Int = 0, pageSize: Int = 10, orderBy: Int = 1, filter: String = "%"): Page[User] = {
    val offset = pageSize * page
    val mode = if (orderBy > 0) "ASC NULLS FIRST" else "DESC NULLS LAST"

    Logger.debug("Users.list with params: page[%d] pageSize[%d] orderBy[%d] filter[%s] order[%s]".format(page, pageSize, orderBy, filter, mode))

    DB.withConnection {
      implicit connection =>

        val users = SQL(
          """
            select * from publisher
            where name ilike {filter}
            order by {orderBy} %s
            limit {pageSize} offset {offset}
          """.format(mode)
        ).on(
          'pageSize -> pageSize,
          'offset -> offset,
          'filter -> filter,
          'orderBy -> scala.math.abs(orderBy)
        ).as(User.simple *)

        val totalRows = SQL(
          """
            select count(*) from publisher
            where name like {filter}
          """
        ).on(
          'filter -> filter
        ).as(scalar[Long].single)

        Page(users, page, offset, totalRows)
    }

  }

Doesn't matter which value of 'orderBy' I provide, the order is always based on id of the entities. 无论我提供的'orderBy'值是什么,订单总是基于实体的id。

The query generated by Anorm is valid PostgreSQL and it works fine when running it against the database directly. Anorm生成的查询是有效的PostgreSQL,它直接对数据库运行时工作正常。 But it seems like if Anorm parser was ignoring the order in which the results are returned, and instead returns a list ordered by 'id'. 但似乎Anorm解析器忽略了返回结果的顺序,而是返回按'id'排序的列表。

I've even tried to simplify the query to a "select * from publisher order by 2 ASC/DESC" , but nothing is fixed, the ordering is ignored by Anorm on return. 我甚至试图将查询简化为"select * from publisher order by 2 ASC/DESC" ,但没有修复,Anorm在返回时忽略了这个顺序。

Any suggestion on how to solve this issue? 关于如何解决这个问题的任何建议?

Thanks to Guillaume on the mailing list of Play I found a workaround. 感谢Play的邮件列表中的Guillaume,我找到了一个解决方法。

All placeholders work except the one in order by. 所有占位符都按顺序排列。 The worse part is that when you follow the logs, the driver generates the correct query and PostgreSQL is receiving it. 更糟糕的是,当您按照日志时,驱动程序会生成正确的查询,而PostgreSQL正在接收它。 I'm not sure what's the deal, very confusing, but if I remove that placeholder, it just works. 我不确定这笔交易是什么,非常令人困惑,但是如果我删除那个占位符,它就会起作用。

Depressing :( 沉闷 :(

I solved it like this: 我这样解决了:

val users = SQL(
  """
    select * from publisher
    where name ilike {filter}
    order by %d %s
    limit {pageSize} offset {offset}
  """.format(scala.math.abs(orderBy), mode)
).on(
  'pageSize -> pageSize,
  'offset -> offset,
  'filter -> filter
).as(User.simple *)

Now you'll be screaming "SQL INJECTION". 现在你会尖叫“SQL INJECTION”。 Relax. 放松。 Although it may be possible somehow, orderBy is an integer (which we turn into abs value for more safety). 虽然有可能以某种方式, orderBy是一个整数(为了更安全,我们将其变为abs值)。 If you try to call the controller that provides orderBy with a string, Play returns a 404 error. 如果您尝试使用字符串调用提供orderBy的控制器,则Play会返回404错误。 So only integers are allowed. 所以只允许整数。 And if there is no column corresponding to the given integer, the order by is ignored. 如果没有与给定整数对应的列order by则忽略order by So, not ideal, but not so bad. 所以,不理想,但不是那么糟糕。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM