簡體   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