Answers:
我最喜欢动态查询的条件查询。例如,动态添加一些订购或根据某些参数省去某些零件(例如限制)要容易得多。
另一方面,我将HQL用于静态和复杂查询,因为它更易于理解/阅读HQL。另外,我认为HQL功能更强大,例如对于不同的联接类型。
HQL和criteriaQuery之间在性能方面有所不同,每次您使用criteriaQuery触发查询时,它都会为表名创建一个新别名,该别名不会反映在任何数据库的上一个查询缓存中。这导致编译生成的SQL的开销,需要更多的时间来执行。
关于获取策略[http://www.hibernate.org/315.html]
- 条件遵循映射中的惰性设置,并确保已加载要加载的内容。这意味着一个条件查询可能会导致多个SQL立即执行SELECT语句,以使用所有非延迟映射的关联和集合来获取子图。如果要更改“方式”,甚至要更改“内容”,请使用setFetchMode()启用或禁用特定集合或关联的外部联接获取。条件查询也完全尊重提取策略(联接,选择,子选择)。
- HQL尊重映射中的延迟设置,并确保已加载要加载的内容。这意味着一个HQL查询可能会导致多个SQL立即SELECT语句来获取具有所有非延迟映射的关联和集合的子图。如果要更改“方式”,甚至要更改“内容”,请使用LEFT JOIN FETCH启用特定集合的外部联接获取或可空的多对一或一对一关联,或使用JOIN FETCH启用内部联接获取非空多对一或一对一关联。HQL查询不遵守映射文档中定义的任何fetch =“ join”。
Criteria是一种面向对象的API,而HQL则是字符串连接。这意味着适用面向对象的所有好处:
由于HQL非常像SQL(大多数开发人员已经很了解),所以这些“不必记住”的参数就没有那么重要了。如果HQL更加不同,那么这将更加重要。
当我不知道在哪些数据上使用什么输入时,我通常使用Criteria。就像在搜索表单上,用户可以输入1到50个项目中的任何一个,我不知道他们将搜索什么。在检查用户要搜索的内容时,将更多内容附加到条件上非常容易。我认为在这种情况下进行HQL查询会有些麻烦。当我完全知道自己想要什么时,HQL很棒。
条件是指定自然键查找的唯一方法,该方法利用二级查询缓存中的特殊优化。HQL没有任何方法可以指定必要的提示。
您可以在此处找到更多信息:
Criteria Api是Hibernate的良好概念之一。根据我的观点,这些是我们可以区分HQL和Criteria Api的几点
limit offset:rows
在hql中,可以避免使用sql注入setParameter
对我而言,条件很容易理解和进行动态查询。但是到目前为止,我说的缺点是它加载了所有多对一关系,因为我们只有三种类型的FetchModes,即选择,代理和默认,并且在所有这些情况下,它都加载了多对一(如果这样的话,我是错的我出来:))
Criteria的第二个问题是它加载了完整的对象,即,如果我只想加载一个雇员的EmpName,它不会提出这个insted,它会提出完整的Employee对象,由于这个问题,我确实可以从中获取EmpName,它确实在报告。就像HQL只是加载(不加载关联/关系)那样,您想要什么,因此可以多次提高性能。
Criteria的一项功能是,由于它具有动态查询生成功能,因此它可以保护您免受SQL Injection的攻击,因为在HQL中,由于ur的查询是固定的或参数化的,因此对于SQL Injection是不安全的。
另外,如果您在ur aspx.cs文件中编写HQL,那么您与UR DAL紧密相关。
总的来说,我的结论是,有些地方像报告一样无法没有HQL,因此可以使用它们,否则Criteria更加易于管理。
Criteria API更适合动态生成的查询。因此,如果您想添加WHERE子句过滤器,JOIN子句或更改ORDER BY子句或投影列,那么Criteria API可以帮助您动态生成查询,同时还可以防止SQL注入攻击。
另一方面,条件查询的表现力较差,甚至可能导致非常复杂且效率低下的SQL查询,如本文所述。
JPQL是JPA标准实体查询语言,而HQL扩展了JPQL并添加了一些特定于Hibernate的功能。
JPQL和HQL表现力很强,类似于SQL。与Criteria API不同,JPQL和HQL使得预测JPA提供程序生成的基础SQL查询变得容易。与标准查询相比,审查一个人的HQL查询也要容易得多。
值得注意的是,如果需要修改使用JPQL或Criteria API的实体,则是有意义的。否则,DTO投影是更好的选择。
如果不需要更改实体查询结构,请使用JPQL或HQL。如果您需要更改过滤或排序标准或更改投影,请使用Criteria API。
但是,仅仅因为您使用的是JPA或Hibernate,并不意味着您不应该使用本机SQL。SQL查询非常有用,并且JPQL和Criteria API不能替代SQL。请查看本文以获取有关此主题的更多详细信息。
对我而言,在Criteria上最大的赢家是Example API,您可以在其中传递对象,然后休眠将基于这些对象属性构建查询。
除此之外,标准API也有其独特之处(我相信休眠团队正在重新设计api),例如:
当我想要类似于sql的查询(从“状态='已阻止”的用户中删除)查询时,我倾向于使用HQL,而当我不想使用字符串附加时,我倾向于使用条件。
HQL的另一个优点是,您可以事先定义所有查询,甚至可以将它们外部化为一个文件左右。
在一开始,我们主要在应用程序中使用Criteria,但由于性能问题,后来将其替换为HQL。
主要是我们使用带有多个联接的非常复杂的查询,这导致在Criteria中产生多个查询,但在HQL中进行了非常优化。
情况是,我们仅对特定对象而不是完整对象使用几种属性。对于Criteria,问题还在于字符串连接。
假设要在HQL中显示用户的姓名和姓氏,这很容易,(name || ' ' || surname)
但是在Crteria中则不可能。
为了克服这个问题,我们使用了ResultTransormers,其中有些方法对所需的结果实施了这种串联。
今天,我们主要使用HQL,如下所示:
String hql = "select " +
"c.uuid as uuid," +
"c.name as name," +
"c.objective as objective," +
"c.startDate as startDate," +
"c.endDate as endDate," +
"c.description as description," +
"s.status as status," +
"t.type as type " +
"from " + Campaign.class.getName() + " c " +
"left join c.type t " +
"left join c.status s";
Query query = hibernateTemplate.getSessionFactory().getCurrentSession().getSession(EntityMode.MAP).createQuery(hql);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();
因此,在本例中,返回的记录是所需属性的映射。
CriteriaUpdate<T>
和CriteriaDelete<T>
供参考。
对于动态查询,我也更喜欢使用条件查询。但是我更喜欢使用hql进行删除查询,例如,如果从子表中删除父ID为'xyz'的所有记录,HQL可以轻松实现,但是对于标准API,我们首先必须触发n个删除查询,其中n是子查询数表记录。
此处的大多数答案都具有误导性,并提到Criteria Queries
比慢HQL
,但实际上并非如此。
如果您深入研究并执行一些测试,您将看到“ 条件查询”的性能要比常规HQL好得多。
而且通过Criteria Query,您可以获得HQL所不具备的面向对象的控件。
有关更多信息,请在此处阅读此答案。