从用户搜索条件动态创建WHERE子句

时间:2009-09-11 13:44:46

标签: java sql

我确信这是一个相当普遍的问题,我不想重新发明轮子。 我有一个搜索表单,用户可以在其中指定搜索条件和搜索类型(AND OR Ext ..)。

表单传回id映射到列名和值的id。目前,我正在使用服务器端Java将字符串粘合到一个where子句中。它在某些情况下有效,但它很笨重,容易出错并且不能很好地扩展。

有什么建议吗?

谢谢,

大卫

7 个答案:

答案 0 :(得分:1)

如果您使用的是ORM(我使用的是Hibernate),您可以使用Criteria API:  它允许您聚集条件(例如使用循环),并构建生成的查询。

在本机SQL中,我不知道会这样做的库。 也许你可以编写自己的,从Hibernate Criteria的文档和代码中获得灵感?


OR:

如果你在客户端做了一些足够复杂的事情(比如你管理AND和OR之间的优先级,你可以使用括号嵌套条件......),那么你可能已经构建了数据结构在客户端处理这个问题。

在这种情况下,我建议您将该数据结构发送到服务器,并通过循环使用它来构建您的查询。

答案 1 :(得分:1)

我会用准备吗?无论如何,如果只是为了避免注入和其他误转换风险。

如果搜索条件的大小有限,您可以静态列出所有可能的查询以供准备。

如果没有,您可以动态维护准备好的查询池。这对于Web应用程序没有用,在那里您可能无法重用您准备的任何查询。

答案 2 :(得分:0)

您必须在客户端或服务器上构建搜索字符串。在客户端上构建它显然不是一个好的解决方案(安全方面),因此唯一的选择是在服务器上构建它。就个人而言,我会使用或构建一个Searcher对象,它可以有效地处理构建搜索字符串的重复任务,并从那里创建一个Statement。

答案 3 :(得分:0)

Hibernate有一个Criteria API,它允许仅使用方法调用创建动态查询,而不需要手动组成sql查询。

但是你应该考虑使用像Lucene或Hibernate Search这样的全文搜索解决方案,这大大减少了对复杂条件查询的需求。全文搜索也是一种更好的用户体验解决方案,因为全文搜索更容易执行,并且通常可以提供更好的结果。

答案 4 :(得分:0)

Massimiliano Fliri建议看看Criteria API让我朝着正确的方向前进。我停止了构建“只是一个where子句”的事情,并开始考虑将此作为构建语句的需要。

这引出了我的解决方案: Squiggle-sql:http://code.google.com/p/squiggle-sql/

来自文档:

  

Squiggle是一个用于动态生成SQL SELECT语句的小型Java库。对于需要使用在运行时更改的条件构建复杂查询的应用程序来说,它的最佳点是。通常,弄清楚如何构建这个字符串可能会非常痛苦。 Squiggle消除了很多痛苦。

答案 5 :(得分:0)

如果您将Hibernate用作ORM,请使用Criteria api执行此操作。根据某些条件添加/删除子句必须更容易。

如果要构建一个jdbc查询,请首先保持该常量的部分并附加变量部分,例如

从trans中选择*,其中userid =?

并根据条件追加例如     如果金额!= null,则追加'和金额> ? '

只要你可以保持恒定部分与变化部分隔离好,你就不应该有太多问题。

答案 6 :(得分:0)

Adam Machanic撰写的“Expert SQL Server 2005开发”一书在第7章中有关于动态SQL的一些很好的建议。他潜入各种问题,包括性能,可维护性和安全性。我不会试图重写他的章节 - 足以说他相信在SQL方面更少。

它特定于SQL Server,但我相信他的一般方法(巨大的where子句与if / then SQL vs. dynamic)可以全面应用。

编辑:我认为值得添加...永远不要信任来自客户端的输入,在SQL中使用它之前总是参数化你的输入。