在我的Wicket + JPA/Hibernate + Spring項目中,許多功能都基於收件箱頁面,在這個頁面中,使用許多過濾選項(並非所有過濾選項都必須使用),用戶可以限制設置他們想要使用的對象。我想知道實施這種過濾的最佳策略是什麼?在此應用程序的舊版本中,搜索查詢是通過串聯包含SQL條件的字符串構建的。最近我閱讀了關於JPA新提供的Criteria API - 你會推薦使用搜索字符串嗎?並且這與DAO層是如何結合在一起的 - 是不是使用業務層中的Criteria API構建搜索查詢,而是違反了層的分離?複雜搜索查詢JPA
回答
對於像你所描述的過濾查詢,我絕對推薦使用Hibernate或JPA標準API,因爲它支持條件查詢。我通常只是將標準構建代碼放入我的DAO中,並將所有必需的(可能爲null)參數傳遞到那裏。
下面是一個例子汽車租賃應用程序中使用Hibernate的標準API的例子DAO方法:
public List<VehicleRentalContract> list(Long contractID,
String customerNameOrID, Date date,
String vehicleDescriptionOrRegistration) {
Criteria criteria = getSession().createCriteria(
VehicleRentalContract.class);
// contractID filter
if (contractID != null && contractID != 0) {
criteria.add(Restrictions.eq("id", contractID));
}
// customerNameOrID filter
if (customerNameOrID != null && customerNameOrID.length() > 0) {
try {
Long customerID = Long.parseLong(customerNameOrID);
criteria.add(Restrictions.eq("customer.id", customerID));
} catch (NumberFormatException e) {
// assume we have a customer name
String customerNameQuery = "%" + customerNameOrID.trim() + "%";
criteria.createAlias("customer", "customer").add(
Restrictions.or(Restrictions.like("customer.firstName",
customerNameQuery), Restrictions.like(
"customer.lastName", customerNameQuery)));
}
}
// date filter
if (date != null) {
criteria.add(Restrictions.and(
Restrictions.le("rentalPeriod.startDate", date),
Restrictions.ge("rentalPeriod.endDate", date)));
}
// vehicleDescriptionOrRegistration filter
if (vehicleDescriptionOrRegistration != null
&& vehicleDescriptionOrRegistration.length() > 0) {
String registrationQuery = "%"
+ Vehicle
.normalizeRegistration(vehicleDescriptionOrRegistration)
+ "%";
String descriptionQuery = "%"
+ vehicleDescriptionOrRegistration.trim() + "%";
criteria.createAlias("vehicle", "vehicle").add(
Restrictions.or(Restrictions.like("vehicle.registration",
registrationQuery), Restrictions.like(
"vehicle.description", descriptionQuery)));
}
List<VehicleRentalContract> contracts = criteria.list();
return contracts;
}
的createAlias調用可以使用,你需要在SQL聯接。
即使我更喜歡使用Criteria而不是HQL和SQL,對我而言,理由將是模塊化和性能,因爲當項目投入生產時,我們面臨的主要問題是性能,無論是HQL還是SQL都無法與Criteria競爭性能。
添加到上面DAO層是爲訪問數據而創建的,該層應該像玻璃一樣清晰,沒有任何複雜的編碼或業務邏輯,但是在標準情況下,必須編寫一個邏輯(創建標準)以獲得更好的和調整的訪問對象的方式,所以在我看來,在DAO層中放置這麼多的邏輯沒有任何缺點。
我不認爲任何高級API都可能超越SQL,因爲它畢竟都是SQL查詢。 – 2010-11-10 08:10:33
兩種方法:
1 ..根據什麼類型的篩選,你需要你可以通過例如搜索以達致這使用Lucene索引所有對象,然後使用搜索查詢執行過濾。例如,建立一個查詢,如:
標題: 「正確的方式」 & mod_date:[20020101 TO 20030101]
參見:http://lucene.apache.org/java/2_4_0/queryparsersyntax.html
2 ..或者用標準...
我會使用新的類型安全標準API從休眠狀態:
是建立了一個非常大的標準,而不是一個方法,我會嘗試使用分離的標準來單獨出所有的邏輯 -
有了這兩者的組合你就可以建立輕鬆制定標準。
另一個尋找靈感的地方是grails動態發現者。這基本上是你試圖以靜態方式實現的。
http://www.grails.org/doc/1.0.x/guide/single.html#5.4.1動態查找
如果你真的願意,你可以實現一個簡單的語法層的完全分離。然後解析這個來創建相關的標準。這將允許更改基礎標準實現。這是否合適取決於這種抽象對你有多重要。
- 1. @ManyToMany JPA 2複雜查詢
- 2. REST和複雜的搜索查詢
- 3. Facebook的圖搜索複雜的查詢
- 4. 複雜codeignitor用戶搜索查詢
- 5. 多組查詢 - jqgrid複雜搜索
- 6. 複雜的YouTube搜索查詢
- 7. 複雜MySQL的搜索查詢
- 8. 複雜的搜索SQL查詢
- 9. 查詢具有更復雜搜索查詢的訂單的API?
- 10. JPA規範複雜的查詢
- 11. 用jpa jpql複雜的sql查詢
- 12. Jqgrid複雜搜索
- 13. 複雜的搜索和查找在Excel
- 14. Lucene複合查詢搜索
- 15. 複雜的mysql搜索查詢,'布爾和'關鍵字搜索mysql字符串
- 16. 谷歌搜索將返回503錯誤複雜的搜索查詢
- 17. 複雜查詢
- 18. 複雜查詢
- 19. 複雜查詢
- 20. 複雜的Oracle SQL搜索查詢優化
- 21. 複雜的mysql搜索查詢條件很少
- 22. Elastic Search中的複雜搜索查詢5
- 23. 複雜的ActiveRecord查詢 - 哈希中搜索
- 24. 涉及搜索連續日期的複雜查詢(按月)
- 25. 具有多值的SQL複雜搜索查詢
- 26. 使用Softlayer對象存儲搜索API編寫複雜查詢
- 27. mySQL中的複雜查詢(在多個表中搜索用戶)
- 28. 如何構建複雜的Google Web搜索查詢?
- 29. 使用MySQL執行復雜的多表搜索查詢
- 30. SQL - 優化複雜的分頁搜索查詢
+1爲基本概念。儘管可以爭論使用customerNameOrID參數。它看起來像嵌套一個「或」成其他「和」相關的參數。如果遇到數據類型相同的情況,這可能變得任意複雜。對於這些情況,最好使用不同的參數集創建重載。 – 2010-10-27 13:41:19
@Adriaan Koster您的參數列表可以替換爲繪製搜索的類,例如** VehicleRentalContractCriteria ** – 2010-10-31 16:49:57
@Martin'customerNameOrID'來自文本輸入字段,用戶可以在其中輸入客戶的一部分名稱或客戶ID。我不太瞭解你如何建議簡化嵌套OR,請告訴我們。 – 2010-11-10 08:02:59