我更喜欢使用Criteria查询来进行动态查询。例如,根据某些参数动态添加一些排序规则或者略过某些部分(例如限制条件),这样会更加容易。
另一方面,对于静态和复杂的查询,我使用HQL,因为它更易于理解和阅读。此外,我认为HQL的功能更加强大,例如支持不同类型的联接操作。
在性能方面,使用criteriaQuery查询每次都会为表名创建一个新的别名,这并不反映在任何数据库中上次查询的缓存中。这导致编译生成的SQL的开销增加,需要更长的执行时间。
关于提取策略 [http://www.hibernate.org/315.html]
- Criteria尊重映射中的惰性设置,并保证加载所需内容。这意味着一个Criteria查询可能会导致多个SQL SELECT语句立即获取所有非惰性映射关联和集合的子图。如果您想更改“如何”甚至“什么”,请使用setFetchMode()为特定集合或关联启用或禁用外部连接提取。 Criteria查询还完全尊重提取策略(联接vs选择vs子选择)。
- HQL尊重映射中的惰性设置,并保证加载所需内容。这意味着一个HQL查询可能会导致多个SQL SELECT语句立即获取所有非惰性映射关联和集合的子图。如果您想更改“如何”甚至“什么”,请使用LEFT JOIN FETCH为特定集合或可为空的多对一或一对一关联启用外部连接提取,或使用JOIN FETCH为非空的多对一或一对一关联启用内部连接提取。 HQL查询不尊重映射文档中定义的任何fetch="join"。
Criteria是面向对象的API,而HQL意味着字符串拼接。这意味着所有面向对象的好处都适用:
由于HQL非常类似于SQL(大多数开发人员已经非常了解),所以这些“无需记忆”的论点并没有太大的分量。如果HQL与SQL更不同,则这将变得更加重要。
当我不知道输入将用于哪些数据时,我通常会使用Criteria。比如在搜索表单中,用户可以输入任何1到50个项目,而我不知道他们要搜索什么。随着我逐步检查用户正在搜索的内容,只需向条件追加更多条件即可非常容易地实现。在这种情况下,我认为将HQL查询放入其中可能会更加麻烦。不过,如果我确切地知道我想要的查询,那么HQL是非常好的。
HQL更容易阅读,使用像Eclipse Hibernate插件这样的工具调试更容易,并且日志记录更容易。 如果需要构建大量行为在运行时决定的动态查询,则Criteria查询更好。 如果您不了解SQL,我可以理解使用Criteria查询,但总的来说,如果我已经预先知道我想要什么,我更喜欢使用HQL。
Criteria API更适合于动态生成的查询。因此,如果您想要添加WHERE子句过滤器、JOIN子句或改变ORDER BY子句或投影列,则Criteria API可以帮助您动态生成查询,同时还可以防止SQL注入攻击。
然而,Criteria查询表达能力较弱,甚至可能导致非常复杂和低效的SQL查询。
JPQL是JPA标准实体查询语言,而HQL扩展了JPQL并添加了一些Hibernate特定的功能。
JPQL和HQL具有极高的表达能力,并且类似于SQL。与Criteria API不同,JPQL和HQL使预测由JPA提供程序生成的底层SQL查询变得容易。同时,检查自己的HQL查询比检查Criteria查询容易得多。
值得注意的是,如果需要修改实体,则使用JPQL或Criteria API选择实体是有意义的。否则,DTO投影是更好的选择。
如果不需要改变实体查询结构,则使用JPQL或HQL。如果需要更改过滤或排序条件或更改投影,则使用Criteria API。
然而,仅仅因为使用JPA或Hibernate,并不意味着不使用原生SQL。SQL查询非常有用,而JPQL和Criteria API并不能替代SQL。
使用查询缓存级别2中的特殊优化来指定自然键查找的标准是唯一的方式。HQL没有任何指定必要提示的方法。
您可以在此处找到更多信息:
Criteria Api是Hibernate中的好概念之一。据我看来,以下是区分HQL和Criteria Api的几个要点:
limit offset:rows
在 HQL 中,您可以使用 setParameter
避免 SQL 注入。 - Viswanath Lekshmanan对我来说,Criteria相当容易理解,并使查询动态化。但我迄今为止发现的缺点是,它加载所有many-one等关系,因为我们只有三种FetchModes,即Select、Proxy和Default,在所有这些情况下,它都会加载many-one(如果我错了,请帮助我:)
Criteria的第二个问题是,它会加载完整的对象,即如果我只想加载员工的EmpName,它不会呈现出来,而是会呈现出完整的Employee对象,我可以从中获取EmpName,由于这个它在报告方面效果很差。而HQL仅仅加载你需要的内容(未加载关联/关系),因此大大提高了性能。
Criteria的一个特点是它会通过动态查询生成来保护您免受SQL注入攻击,而在HQL中,由于您的查询要么是固定的,要么是参数化的,因此不安全。
此外,如果您在aspx.cs文件中编写HQL,则与DAL紧密耦合。
总的来说,我的结论是,在某些地方,您不能没有HQL,比如报告,因此请使用它们,否则Criteria更容易管理。