使用Criteria或HQL的优点和缺点是什么?Criteria API是一种在Hibernate中表达查询的面向对象的好方法,但有时Criteria queries比HQL更难理解/构建。
什么时候使用标准,什么时候使用HQL?在哪些用例中您更喜欢什么?还是说这只是个人口味的问题?
使用Criteria或HQL的优点和缺点是什么?Criteria API是一种在Hibernate中表达查询的面向对象的好方法,但有时Criteria queries比HQL更难理解/构建。
什么时候使用标准,什么时候使用HQL?在哪些用例中您更喜欢什么?还是说这只是个人口味的问题?
当前回答
对我来说,Criteria最大的优势是示例API,在这里你可以传递一个对象,hibernate将基于这些对象属性构建一个查询。
除此之外,标准API也有它的怪癖(我相信hibernate团队正在重做API),比如:
a criteria.createAlias("obj")强制使用内部连接而不是可能的外部连接 您不能两次创建相同的别名 有些SQL子句没有简单的对应条件(比如子选择) 等。
当我想要类似于sql的查询时,我倾向于使用HQL(从用户中删除status='blocked'),当我不想使用字符串追加时,我倾向于使用标准。
HQL的另一个优点是您可以预先定义所有的查询,甚至可以将它们外部化到一个文件中。
其他回答
对于动态查询,我更喜欢使用条件查询。例如,根据某些参数,动态地添加一些排序或保留一些部分(例如限制)要容易得多。
另一方面,我使用HQL进行静态和复杂的查询,因为它更容易理解/阅读HQL。此外,我认为HQL更强大一些,例如对于不同的连接类型。
另一点是,我认为Criteria更适合在它的基础上构建,而不是在最终代码中直接使用。
它更适合使用它来构建库,而不是使用jpql或hql。
例如,我使用Criteria API构建了spring-data-jpa-mongodb-expressions(与spring数据QBE的方式相同)。
我认为spring数据查询代使用jpaql而不是标准,我不明白为什么。
我不想在这里白费口舌,但有一点很重要,那就是Criteria查询现在已被弃用。使用HQL。
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.
Criteria是一个面向对象的API,而HQL意味着字符串连接。这意味着面向对象的所有好处都适用:
All else being equal, the OO version is somewhat less prone to error. Any old string could get appended into the HQL query, whereas only valid Criteria objects can make it into a Criteria tree. Effectively, the Criteria classes are more constrained. With auto-complete, the OO is more discoverable (and thus easier to use, for me at least). You don't necessarily need to remember which parts of the query go where; the IDE can help you You also don't need to remember the particulars of the syntax (like which symbols go where). All you need to know is how to call methods and create objects.
由于HQL非常像SQL(大多数开发人员已经非常了解SQL),因此这些“不必记住”参数就没有那么重要了。如果HQL有更大的不同,那么这就更重要了。