Hibernate 4 查询语言

原文: https://javabeginnerstutorial.com/hibernate/hibernate-4-with-query-languages/

在介绍了映射关系和继承的 Hibernate 4 入门之后,让我们更深入地了解如何获取数据库中存储的数据。

如果查看示例应用的main方法,您会发现我正在使用从会话中生成的简单标准查询来列出和计数数据。 加载所有数据以对它们进行计数会过多,并且会占用太多内存。 还有其他方法,让我向他们展示。

HQL 和 JPQL

HQL 是 Hibernate 的默认查询语言(缩写为 Hibernate 查询语言)。 JPQL 用于更通用的 Java 持久性查询语言,它是 HQL 的子集。 这意味着有效的 JQPL 查询也是有效的 HQL 查询-但并非总是如此。

HQL 背后的主要思想是,您可以在查询中使用实体名称,而不是数据库中的表名称。 这使存储和查询更加透明,您可以在开发人员之间划分任务,因为编写查询的人只需要知道实体名称即可。

简单 HQL 查询是一个选择查询:

  1. from Book

是的,您可以在仓库中看到这是一个有效的查询。

如果提及实体,则可以使用其简单名称或实体的限定名称(具有整个包结构)。

除了选择,JPQL 和 HQL 允许更新删除语句。 HQL 也另外提供插入语句。

关于区分大小写的评论

HQL 和 JPQL 中的关键字不区分大小写,这意味着SELECTselectSeLeCt的含义相同。 但是实体名称区分大小写hibernate_example.Bookhibernate_example.BOOK不同。

关于类型安全的评论

HQL 和 JPQL 是非类型安全的查询。 条件查询提供了一种类型安全的方法。

类型安全性是什么意思? 您不必从查询中将对象返回值转换为所需的实体对象。 这就是为什么使用 Hibernate 的默认查询机制时会收到编译时警告的原因。

创建和执行查询

幸运的是,创建和执行查询不需要特定的库,可以通过我们在方法中已经拥有的会话对象来完成。

为了将查询与main方法分开,我添加了信息库类,在其中实现了一些静态函数来查询数据库。

因此,让我们看一下查询创建的不同版本。 它们都具有相同的根:会话对象,但是它们是通过调用不同的方法执行的。

查询是执行查询的最简单方法,也是最常见的查询方法:

  1. session.createQuery("from Book").list();

使用条件可以通过编程方式限制结果集(例如,您需要更少的查询输入,并且可以在调试时轻松注释掉条件行):

  1. session.createCriteria(Author.class).add(Restrictions.like("name", "M%")).list();

上面的查询返回名称以字母M开头的所有作者。

本机查询

有时,编写本机查询会很方便,因为您需要一些仅在您所使用的数据库中可用的特定方法。 幸运的是,Hibernate 也支持本地查询。

本机查询是普通的旧 SQL,您必须在其中使用表名而不是实体名。

区别在于结果类型。 例如,使用 SQL 查询对对象计数会使用 HQL 查询返回BigInteger,而我们会返回 Long。 因此,更改查询时间并不总是透明的,并且会在您的应用中引起一些讨厌的错误。

为什么本地查询会更好? 因为您可以消除 Hibernate 本质上执行的一些连接。

例如,对带有 Hibernate 的Authors进行计数的查询最终会导致以下 SQL:

  1. select count(*) from Author a inner join PERSONS p on a.name = p.name

但是,我们知道数据结构,因此可以说消除了连接:

  1. return (BigInteger) session.createSQLQuery("select count(*) from author").uniqueResult();

缺点自然是我们失去了透明度,并且更改了继承模型以适应查询。

总结

HQL 和 JPQL 是 Hibernate 附带的本机查询语言。 无需任何先决条件即可使用它们。 但是,它们是非类型安全的,这意味着您必须将结果转换为相应的类型,如果无法完成转换,则可能导致运行时异常。

在本文中,我没有显示标准查询,参数化的和准备好的语句-但我将在以后的文章中进行介绍。

代码下载

您可以从 Github 此处下载特定章节的代码。