繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM