2013-04-07 79 views
2

我想使用Anorm使用返回匹配行为一组ID的查询返回结果列表。例如。Play Framework 2.0使用Anorm在查询中表示集合的正确方法

select * 
from example 
where id in (1,2,3,4,5) 

如果我尝试

SQL(
    """ 
     select * 
     from example 
     where id in ({ids}) 
    """ 
).on('ids -> ids).as(int("id") ~ str("name") *) 

其中IDS是字符串 “1,2,3,4,5”,它只会返回第一行。注入这组ID的正确方法是什么?

回答

5

有没有简单的方法做AFAIK。

这是我如何解决它:

def findSomething(ids: String) = { 
    // Split up the comma separated values 
    val sids = ids split "," 
    // Create a list of keys (id0, id1, id2, ...) 
    val keys = for (i <- 0 until sids.size) yield ("id" + i) 
    // Create a seq of parameterized values 
    val values = sids map (toParameterValue(_)) 

    // Now zip together the keys and values into list of tuples 
    val params = keys zip values 

    DB.withConnection { implicit connection => 
    SQL(
     """ 
     select * 
     from example 
     where id in ({%s}) 
     """.format(keys.mkString("},{")) 
    ).on(
     params: _* 
    ).as(
     int("id") ~ str("name") * 
    ) 
    } 
} 

NB
这里的cruical部分是在SQL语句格式的字符串。如果你没有完全控制你的输入参数,那么它很容易被SQL注入。

+0

太棒了!感谢这些信息,无论如何,我觉得我做错了。 – 2013-04-08 18:37:34

+0

谢谢,但这仍然有点疯狂,并且anorm需要支持参数化序列。更不用说使用字符串中的“scala noob expected-to-work”绑定技术在记录器中产生完全有效的SQL,但是却悄无声息地失败了。 – Brian 2013-04-10 15:18:20

+0

@notbrain在Play开发团队已经讨论了很多次,[这里](https://groups.google.com/forum/?fromgroups=#!topic/play-framework/meYkd-KKQRE),[这里](http://play.lighthouseapp.com/projects/82401/tickets/188-make-in-clause-in-anorm-easier)和[这里](https://groups.google.com/forum/? fromgroups =#!topic/play-framework/BNFvma2vu5U)。但我完全同意你的看法,这应该是固定的。我在这里的答案只是解决了anorm和IN条款缺点的一种方法。 – maba 2013-04-10 15:39:27

相关问题