正如我们在限制章节中讨论的,我们尚未完全实现 Hibernate 核心 API。此限制适用于ShardedCriteriaImpl,它是Criteria接口的分片感知型实现。在本章节中,我们不会详细讨论具体尚未实现的项目。相反,我们将讨论在Criteria分片环境中存在问题的查询类型。
简单地说,对排序的查询存在问题。原因是什么?因为如果没有能力将列表中的任何值与列表中的其他值进行比较,就无法返回已正确排序的列表,而直到在应用程序层收集单个查询的结果之前,整个列表才可用。排序必须在 Hibernate Shards 内进行,为了完成这项任务,我们需要Criteria使用 order-by 子句进行查询返回的所有对象都实现Comparable接口。如果您返回的对象类型不实现该接口,您将收到异常信息。
不同的子句同样存在问题。实际上,我们此时甚至都不支持它们。对于这一点深表歉意。
另一方面,尽管不同和 order-by 存在问题,但聚合却工作的很好。考虑以下示例
// fetch the average of all temperatures recorded since last thursday Criteria crit = session.createCriteria(WeatherReport.class); crit.add(Restrictions.gt("timestamp", lastThursday)); crit.setProjection(Projections.avg("temperature")); return crit.list();
在单分片环境中,此查询可以轻易得到解答,但在多分片环境中,这会变得有些棘手。原因是什么?仅仅获取每个分片中的平均数不足以计算所有分片中的平均数。为了计算这部分信息,我们不仅需要平均数,还需要每个分片中的记录数。这正是我们的做法,这种做法产生的性能影响(在每个查询中都额外执行计数操作)很可能可以忽略不计。现在,如果我们需要中值,我们就会遇到麻烦(仅仅将计数添加到查询中并不能提供足够的信息来执行计算),但目前Criteria不会公开中值函数,因此,如果中值函数成为问题,我们会予以解决。
我们的 HQL 支持在目前还远不如Criteria查询。我们尚未实现查询解析器的任何扩展,因此我们不支持查询表达式、排序或聚合。这意味着您只能将 HQL 用于非常简单的查询。如果您能避免,最好还是远离此版本中的 HQL。