我确信这是一个相当普遍的问题,我不想重新发明轮子。 我有一个搜索表单,用户可以在其中指定搜索条件和搜索类型(AND OR Ext ..)。
表单传回id映射到列名和值的id。目前,我正在使用服务器端Java将字符串粘合到一个where子句中。它在某些情况下有效,但它很笨重,容易出错并且不能很好地扩展。
有什么建议吗?
谢谢,
大卫
答案 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中使用它之前总是参数化你的输入。