在我的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