在我的应用程序中,通过使用像QueryBuilder.groovy这样的单独脚本附加第一部分(where子句)和第二部分(order by)来构建查询,因此按部分顺序易于HQL注入,这可以使用命名参数进行清理。因此,我想使用findAll通过分别传递查询和排序和分页参数来检索一组记录。我看到了这样的实现:
domainClass.findAll(query,[namedParams],[max: 10, offset: 5])
当我将sortColumn和sortDirection作为命名参数传递时,sortColumn工作正常,但sortDirection不起作用。我需要一种方法来使sortDirection作为命名参数或任何其他方式将“按方向排序”与findAll结果相结合。许多人在各种论坛上建议直接将参数作为查询的一部分使用,但这对我的应用程序来说是不可接受的,因为它会将查询暴露给HQL注入。 提前谢谢。
这是一个例子:
queryString = "FROM BookCatalog b WHERE b.bookNumber = :bookNumber"
这会传递给QueryBuilder.groovy,会发生类似这样的事情:
sort = "$params.sortColumn $params.sortDirection"
queryString.order(sort)
public void sort(String query){
this.query = this.query+" order by "+query
}
最后findAll检索记录列表:
def list = findAll(queryString,namedParams,queryParams)
因为逻辑只是将排序参数附加到查询字符串,潜在的黑客可以做这样的事情:
bookCatalogView?offset=2&max=5&sortColumn=1,2,3 **or 1=1**
或
bookCatalogView?offset=2&max=5&sortColumn=1,2,3;**select * from whatever**
答案 0 :(得分:1)
不要连字符串,这是不好的做法。
如果要创建复杂查询,请考虑使用createCriteria()
SomeDomainClass.createCriteria().list {
order("propName", "desc")
}
或者,如果您需要更多控制,请使用sessionFactory方式:
query = sessionFactory.getCurrentSession().createCriteria(DomainClass.class)
query.addOrder(Order.asc("someField"))
query.addOrder(Order.desc("someotherField"))