使用Criteria或HQL的优点和缺点是什么?Criteria API是一种在Hibernate中表达查询的面向对象的好方法,但有时Criteria queries比HQL更难理解/构建。
什么时候使用标准,什么时候使用HQL?在哪些用例中您更喜欢什么?还是说这只是个人口味的问题?
使用Criteria或HQL的优点和缺点是什么?Criteria API是一种在Hibernate中表达查询的面向对象的好方法,但有时Criteria queries比HQL更难理解/构建。
什么时候使用标准,什么时候使用HQL?在哪些用例中您更喜欢什么?还是说这只是个人口味的问题?
当前回答
标准API
Criteria API更适合动态生成查询。因此,如果您想添加WHERE子句过滤器、JOIN子句,或者改变ORDER BY子句或投影列,Criteria API可以帮助您以一种防止SQL注入攻击的方式动态生成查询。
另一方面,Criteria查询表达能力较差,甚至可能导致非常复杂和低效的SQL查询。
JPQL和HQL
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的替代品。
其他回答
HQL和criteriaQuery在性能上是有区别的,每次你使用criteriaQuery发起查询时,它会为表名创建一个新的别名,这个别名不会反映在任何DB的最后一个查询缓存中。这会导致编译生成的SQL的开销,需要更多的时间来执行。
关于抓取策略[http://www.hibernate.org/315.html]
Criteria respects the laziness settings in your mappings and guarantees that what you want loaded is loaded. This means one Criteria query might result in several SQL immediate SELECT statements to fetch the subgraph with all non-lazy mapped associations and collections. If you want to change the "how" and even the "what", use setFetchMode() to enable or disable outer join fetching for a particular collection or association. Criteria queries also completely respect the fetching strategy (join vs select vs subselect). HQL respects the laziness settings in your mappings and guarantees that what you want loaded is loaded. This means one HQL query might result in several SQL immediate SELECT statements to fetch the subgraph with all non-lazy mapped associations and collections. If you want to change the "how" and even the "what", use LEFT JOIN FETCH to enable outer-join fetching for a particular collection or nullable many-to-one or one-to-one association, or JOIN FETCH to enable inner join fetching for a non-nullable many-to-one or one-to-one association. HQL queries do not respect any fetch="join" defined in the mapping document.
条件是指定利用第二级查询缓存中的特殊优化的自然键查找的唯一方法。HQL没有任何方法来指定必要的提示。
你可以在这里找到更多信息:
http://tech.puredanger.com/2009/07/10/hibernate-query-cache/
还有另一种方法。我最终创建了一个基于hibernate原始语法的HQL解析器,这样它就可以首先解析HQL,然后动态地注入动态参数或自动为HQL查询添加一些通用过滤器。效果很好!
对于动态查询,我也更喜欢使用条件查询。但我更喜欢hql删除查询,例如,如果从父id 'xyz'的子表中删除所有记录,这很容易由hql实现,但对于标准API,首先我们必须触发n个删除查询,其中n是子表记录的数量。
我不想在这里白费口舌,但有一点很重要,那就是Criteria查询现在已被弃用。使用HQL。