<p><strong>摘要</strong>:在本教程中,我们将讨论如何在 PostgreSQL 中使用 Hibernate 查询语言(HQL)。</p>
目录
Hibernate 是一个可以使用在 PostgreSQL 上的 ORM 框架。在这里,我们将讨论它的查询语言 HQL。
HQL 的语法与 SQL 的语法非常接近,因此任何了解 SQL 的人都应该能够很快上手。主要区别在于,HQL 处理的是对象及其属性,而不是处理表和列。从本质上讲,它是一种完整的面向对象语言,用于使用 Java 对象及其属性来查询数据库。与 SQL 不同的是,HQL 能够理解对象的继承、多态性和关联。用 HQL 编写的代码,在运行时会由 Hibernate 转换为 SQL,并在 PostgreSQL 数据库上面执行。
这里需要注意的重要一点是,在 HQL 中对对象及其属性的引用是区分大小写的;所有其他结构均不区分大小写。
使用 HQL 的主要动力是数据库可移植性。由于它的实现设计为与数据库无关,因此,如果您的应用程序使用 HQL 查询数据库,则可以通过对 XML 配置文件进行简单的更改,来更换底层数据库。与原生 SQL 不一样,如果您的应用程序开始与不同的数据库通信,实际代码将基本保持不变。
HQL 实现的完整特性列表可以在他们的网站上找到。在这里,我们提供了一些基本和亮点特性的示例,这些特性可帮助您开始使用 HQL。这些示例使用一个名为 ’largecities’ 的表,其中列出了世界上最大的 10 个大都市。表的描述信息和数据如下:
HQL 作用在此表映射到的类上面,以便使用其数据在内存中创建对象。该类定义为:
请注意 @Entity 和 @Id 注释,它们将类 ‘LargeCities’ 声明为实体,将属性 ‘rank’ 声明为标识符。
如果要将表的所有行作为内存中的对象加载,可使用 FROM 子句。下面给出的示例代码,从表 ’largecities’ 中检索所有行,并列出对象的数据到 stdout。
请注意,HQL 查询中引用的 ‘LargeCities’ 不是 ’largecities’ 表,而是 ‘LargeCities’ 类。这就是 HQL 面向对象的本质。
上面程序的输出如下:
在某些情况下,您可能希望为要查看的对象指定筛选条件。以上面的例子为例,您可能只想查看世界上排名前 5 的大都市。WHERE 子句可以帮助您实现此目的,如下所示:
上述代码的输出为:
默认的 FROM 子句,检索表中的所有列,以作为 Java 中对象的属性。在某些情况下,您只想检索选定的属性,而不是所有属性。在这种情况下,您可以指定一个 SELECT 子句来标识要检索的特定列。
下面的代码仅选定了城市名称进行检索。注意,因为它现在只检索了一列,所以 Hibernate 会把它加载为一个 String 列表,而不是一个 LargeCities 对象的列表。
该代码的输出为:
与预备语句非常相似,您可以拥有命名参数,通过这些参数,您可以在运行时使用变量为 HQL 查询分配值。下面的示例使用了命名参数,来查找 ‘Beijing’ 的排名。
此代码的输出:
编程时,会出现许多需要按块或页的形式处理数据的场景。这个过程称为数据分页,HQL 提供了一种机制来处理这个问题,这需要结合使用 Query 接口的 setFirstResult 和 setMaxResults 方法。顾名思义,setFirstResult 允许您指定哪条记录应作为记录检索的起点,而 setMaxResults 允许您指定要检索的最大记录数。这种组合在 Java 或 Web 应用程序中非常有用,在这些应用程序中,大型结果集被拆分为多个页面,并且用户能够指定页面大小。
下面代码将我们的 ’largecities’ 示例分成 2 个页面,并按页检索数据。
这里要记住的一个重点是,Hibernate 通常是在内存中而不是在数据库查询级别进行分页。这意味着对于大型数据集,使用游标、临时表或其他一些构造进行分页可能会更高效。
Hibernate 网站上提供了完整的特性列表,在这里值得一提的有:
- UPDATE 子句
- DELETE 子句
- INSERT 子句
- JOIN
聚合方法
- avg
- count
- max
- min
- sum
HQL 为其用户提供了很大的灵活性和丰富的功能集,供用户在与数据库通信时使用。然而,灵活性确实是有代价的。由于 HQL 设计为通用的,并且在很大程度上与数据库无关,因此在使用 HQL 时应注意以下事项。
- 有时,您需要使用 PostgreSQL 特定的高级特性和功能。例如,您可能希望利用新引入的 JSONB 数据类型的强大功能。或者,您可能希望使用窗口函数来分析数据。因为 HQL 试图尽可能地通用,所以为了使用这些高级功能,你需要退回到原生 SQL。
- 由于左连接的设计方式,如果您以一对多或多对多的形式,将一个对象连接到另一个表/对象,则可能会获得重复数据。在有级联的左连接情况下,这个问题会更加严重,HQL 必须保留对这些重复项的引用,最终基本上会传输大量的重复数据。这可能会显著影响性能。
- 因为 HQL 自身会做对象关系映射,所以你无法完全控制如何获取数据以及获取哪些数据。有这样一个臭名昭著的问题,那就是 N+1 问题。尽管您可以在 HQL 中找到解决方法,但有时候问题定位会变得非常棘手。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/11099.html