QueryDSL中包含通配符的字符串的精确匹配
在我們最近的一個項目中,我們的客戶要求一個搜索字段,該字段可以搜索名字,姓氏和電子郵件地址,唯一的通配符是星號“ *”,表示部分匹配。 聽起來很簡單,但它使我們陷入了混亂。 在我們的項目中,我們將QueryDSL與JPA和MySQL結合使用作為基礎關系數據庫管理系統。
這意味著默認通配符對于一個字符為'_',對于多個字符為'%'。 支持“ *”進行部分匹配很容易:我們只需在搜索字符串中將“ *”替換為“%”,然后再將其作為值傳遞給JPA Query LIKE表達式即可。
我們的代碼如下所示:
searchText = searchText.replace( "*", "%" ); query.where( user.email.like( searchText ).or(user.firstName.like( searchText ).or(user.lastName.like( searchText )) ) )在此時搜索firstname_lastname@example.org時,當前查詢仍返回兩個結果:firstname_lastname@example.org和firstname.lastname@example.org。
當然,'_'通配符需要轉義。 但是,事實證明,這并不是那么簡單。
根據JPQLTemplates類的定義,默認轉義字符為'!'。 這意味著,在搜索字符串替換“_”由“!_” 應該是足夠了。
searchText = searchText.replace( "_", "!_" ); searchText = searchText.replace( "*", "%" );但是,測試表明事實并非如此。 經過一些調試,然后打開SQL日志記錄(默認情況下我們將其關閉),我們發現生成的SQL解析為:
SELECT * FROM users WHERE email like 'firstname!!_lastname@example.org' escape '!';
事實證明轉義字符本身已被轉義。 最初,我們的Google Fu使我們有些失敗,但后來從2013年開始偶然發現了GitHub問題 。
顯然,只有通過明確說明轉義字符才能強制進行實際轉義 ,即使它與默認轉義字符相同也是如此。
將轉義符添加到QueryDSL表達式中解決了我們的問題:
searchText = searchText.replace( "_", "!_" ); searchText = searchText.replace( "*", "%" ); query.where( user.email.like( searchText, '!' ).or(user.firstName.like( searchText, '!' ).or(user.lastName.like( searchText, '!' )) ) )解決我們想要的SQL:
SELECT * FROM users WHERE email like 'firstname!_lastname@example.org' escape '!';
并生成滿足客戶要求的搜索結果:firstname_lastname@example.org
這是我們永遠不會忘記的!
翻譯自: https://www.javacodegeeks.com/2018/06/matching-string-wild-card-querydsl.html
總結
以上是生活随笔為你收集整理的QueryDSL中包含通配符的字符串的精确匹配的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 甘肃有什么特产(甘肃闻名全国的特产)
- 下一篇: cad重合命令快捷键(cad的重置快捷键