[英]Dynamic create WHERE clause from user Search criteria
我有一个我确定是一个相当普遍的问题,我不想重新发明轮子。 我有一个搜索表单,用户可以在其中指定搜索条件和搜索类型(AND OR Ext ..)。
表单传回id映射到列名和值的id。 目前,我正在使用服务器端Java将字符串粘合到一个where子句中。 它在某些情况下有效,但它很笨重,容易出错并且不能很好地扩展。
有什么建议么?
谢谢,
大卫
如果您使用的是ORM(我使用的是Hibernate),您可以使用Criteria API:它可以让您重新聚合条件(例如使用循环),并构建生成的查询。
在本机SQL中,我不知道会这样做的库。 也许你可以编写自己的,从Hibernate Criteria的文档和代码中获得一些灵感?
要么:
如果你在客户端做了一些足够复杂的事情(比如你管理AND和OR之间的优先级,你可以使用括号嵌套条件......),那么你可能已经构建了一个在客户端处理这个问题的数据结构 。
在这种情况下,我建议您将该数据结构发送到服务器,并通过循环使用它来构建您的查询。
我用准备和? 无论如何,如果只是为了避免注入和其他误转换风险。
如果搜索条件的大小有限,您可以静态列出要准备的所有可能的查询。
如果没有,您可以动态维护准备好的查询池。 这对于Web应用程序没有用处,您可能无法重用您准备的任何查询。
您必须在客户端或服务器上构建搜索字符串。 在客户端上构建它显然不是一个好的解决方案(安全方面),因此唯一的选择是在服务器上构建它。 就个人而言,我会使用或构建一个Searcher对象,它可以有效地处理构建搜索字符串的重复任务,并从那里创建一个Statement。
Hibernate有一个Criteria API,它允许仅使用方法调用创建动态查询,而无需手动组成sql查询。
但是你应该考虑使用像Lucene或Hibernate Search这样的全文搜索解决方案,这大大减少了对复杂条件查询的需求。 全文搜索也是一种更好的用户体验解决方案,因为全文搜索更容易执行,通常可以提供更好的结果。
Massimiliano Fliri建议看看Criteria API让我朝着正确的方向前进。 我停止了构建“只是一个where子句”的事情,并开始考虑将此作为构建语句的需要。
这引出了我的解决方案:Squiggle-sql: http : //code.google.com/p/squiggle-sql/
来自文档:
Squiggle是一个用于动态生成SQL SELECT语句的小型Java库。 对于需要使用在运行时更改的条件构建复杂查询的应用程序来说,它的最佳点是。 通常,弄清楚如何构建这个字符串可能会非常痛苦。 Squiggle消除了很多痛苦。
如果您使用Hibernate作为ORM,那么使用Criteria api来执行此操作。 根据某些条件添加/删除子句必须更容易。
如果要构建jdbc查询,请首先保持该常量的部分,并附加变量部分,例如
select * from trans where userid =?
并根据条件附加,例如
如果金额!= null然后追加'和金额>? “
只要你可以保持恒定部分与变化部分隔离良好,你就不会有太多问题。
Adam Machanic的“Expert SQL Server 2005开发”一书在第7章中有关于动态SQL的一些很好的建议。 他潜入各种问题,包括性能,可维护性和安全性。 我不会试图重写他的章节 - 足以说他相信在SQL方面更少。
它是特定于SQL Server但我相信他的一般方法(巨大的where子句与if / then SQL与动态)可以全面应用。
编辑:我认为值得添加...永远不要信任来自客户端的输入,在SQL中使用它之前总是参数化你的输入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.