# 带有查询语言的 Hibernate 4

> 原文： [https://javabeginnerstutorial.com/hibernate/hibernate-4-with-query-languages/](https://javabeginnerstutorial.com/hibernate/hibernate-4-with-query-languages/)

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

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

## HQL 和 JPQL

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

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

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

```java
from Book
```

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

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

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

### 关于区分大小写的评论

HQL 和 JPQL 中的关键字不区分大小写，这意味着`SELECT`，`select`和`SeLeCt`的含义相同。 但是实体名称**区分大小写**： `hibernate_example.Book`与`hibernate_example.BOOK`不同。

### 关于类型安全的评论

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

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

## 创建和执行查询

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

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

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

查询是执行查询的最简单方法，也是最常见的查询方法：

```java
session.createQuery("from Book").list();
```

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

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

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

## 本机查询

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

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

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

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

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

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

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

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

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

## 结论

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

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

#### 代码下载

您可以从 Github [此处](https://github.com/JBTAdmin/Hibernate)下载特定章节的代码。

