2012-03-19 57 views
3

我正在嘗試構建一個像「計算機」示例中那樣的列表頁面。我的環境是播放2.0和9.0 PostrgreSQL在PostgreSQL 9.0中破解的Anorm與Order By一起選擇?

我在我的用戶對象的下列方法:,訂單總是基於的ID

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) 
    } 

    } 

沒關係的「排序依據」我提供價值實體。

Anorm生成的查詢是有效的PostgreSQL,它直接在數據庫上運行時工作正常。但是,好像Anorm解析器忽略了返回結果的順序,而是返回一個按'id'排序的列表。

我甚至試圖簡化查詢到"select * from publisher order by 2 ASC/DESC",但沒有什麼是固定的,Anorm在返回時忽略了排序。

有關如何解決此問題的任何建議?

回答

4

感謝Guillaume在Play郵件列表中找到了解決方法。

所有佔位符的工作除了按順序之外。更糟糕的是,當你關注日誌時,驅動程序會生成正確的查詢,並且PostgreSQL正在接收它。我不確定這筆交易是什麼,非常混亂,但是如果我移除了那個佔位符,它就會起作用。

踩下:(

我解決了它這樣的:。

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 *) 

現在,你會尖叫「SQL注入」放鬆雖然有可能以某種方式,orderBy是一個整數(爲了更安全,我們轉爲abs值)如果您嘗試使用字符串調用提供orderBy的控制器,則Play會返回404錯誤,因此只允許使用整數,並且如果沒有對應給定整數的列,則order by被忽略,所以,不理想,但不是太糟糕,