llms.txt: machine-readable documentation index. Markdown version of this page is also available.

IntelliJ IDEA 2026.3 Help

Hibernate 调试器

安装 Hibernate Debugger 插件

Hibernate 调试器 是一个 IntelliJ IDEA 插件,可用于检查应用程序中运行的数据库查询,并将其追溯到代码中触发这些查询的位置。 它适用于直接使用 Hibernate 6 或更高版本,或通过 Spring 等框架使用它的应用程序。

正在运行的 Spring 调试器会话中的 Hibernate Debugger 日志条目

可以使用 Hibernate Debugger 执行以下调试任务:

  • 检查特定操作触发的 HQL 语句,以及 Hibernate 因此发送到数据库的 SQL。

  • 查找慢查询和潜在的 N+1 问题。

  • 定位触发特定查询的代码。

  • 在 IDE 中重新运行捕获的 HQL 和 SQL。

  • 探索应用程序连接到的数据库。

前提

记录并检查数据库查询

Hibernate Debugger 在 IntelliJ IDEA 调试器 内运行。 每当应用程序在调试会话期间通过 Hibernate 运行查询时,插件都会在调试器控制台中记录其相关信息。 日志会显示已执行的 SQL 和任何相关的 HQL,以及执行时间、事务 ID 和触发查询的代码等运行时详细信息。

查询记录默认开启。

使用 Hibernate Debugger 检查查询

  1. 开始调试会话。

  2. 在应用程序中,执行与数据库交互的操作。

  3. 转到 Debug 工具窗口并打开 控制台 选项卡。

  4. 查找所执行操作的 Hibernate Debugger 日志条目。 每个条目都会折叠为一个突出显示的行,并显示已执行的 SQL 语句。

    Debug 工具窗口的 Console 选项卡中突出显示 Hibernate Debugger 条目的行
  5. 点击突出显示的行以打开日志条目。

    展开的 Hibernate Debugger 日志条目

要了解如何解读日志条目,请参阅 参考:Hibernate Debugger 日志条目。

筛选已记录的查询

  1. 调试会话运行时,转到 调试 工具窗口并打开 控制台 选项卡。

  2. 在调试器工具栏中,点击 Hibernate Debugger 图标SQL 日志设置和筛选器。

  3. 选择一个或多个筛选器:

    • 仅显示疑似 N+1 查询 :仅显示来自疑似存在 N+1 问题的事务的查询。 随后可以 在代码中跟踪其来源。

    • 按时长筛选 :指定以毫秒为单位的最短时长,以仅显示执行时间达到或超过该时长的查询。

    • 按事务使用筛选器 :指定事务 ID,以仅显示在此事务中执行的查询。

如果选择多个筛选器,则只会显示与所有筛选器都匹配的日志条目。 筛选器应用于当前调试会话,并在关闭会话选项卡时清除。

识别 N+1 查询并在代码中跟踪其来源

N+1 查询问题是使用对象关系映射(ORM)框架的应用程序中的常见性能问题。 当应用程序运行一个查询来提取记录列表,然后又为每条记录运行单独的查询来提取相关数据时,就会出现此问题。

Hibernate Debugger 会检测存在潜在 N+1 查询的事务,并允许筛选掉其他事务中的查询。

  1. 开始调试会话。

  2. 在应用程序中,调用要检查是否存在 N+1 查询的操作。

  3. 转到 调试 工具窗口并打开 控制台 选项卡。

  4. 在调试器工具栏中,点击 Hibernate Debugger 图标SQL 日志设置和筛选器 并选择 仅显示疑似 N+1 查询。

  5. 查找共享相同事务 ID 和 SQL 查询的突出显示行。

    筛选疑似 N+1 查询后,具有相同事务 ID 和 SQL 查询的突出显示 Hibernate Debugger 日志条目
  6. 点击其中一个突出显示的行以打开其日志条目,然后展开其 Invocation stack 部分。 其中包含导致重复查询执行的方法调用序列。

    Debug 工具窗口中展开了疑似 N+1 查询的 Invocation stack 部分
  7. 找到以项目代码中的文件名和行号结尾的最上方堆栈行(不是库或框架生成的代码),然后点击它们。

IntelliJ IDEA 会在代码触发查询的行处打开文件。 检查该方法、其周围代码以及调用它的方法,以找出查询反复运行的原因。

停止记录查询

  1. 调试会话运行时,转到 调试 工具窗口。

  2. 在调试器工具栏中,点击 Hibernate Debugger 图标SQL 日志设置和筛选器 并清除 记录数据库查询日志 选项。

    Hibernate Debugger SQL Log Settings and Filters 框中已清除 Log database queries 选项

关闭查询记录会应用于项目中的所有调试会话。 可以随时再次选择 记录数据库查询日志 将其重新开启。

重新运行捕获的查询

可以重新运行 Hibernate Debugger 捕获的查询,而无需在应用程序中再次触发这些查询。 HQL 语句会在 JPA Console 中重新运行,SQL 语句会在 query console 中重新运行。

重新运行 HQL 查询

例如,当想要检查查询提取了哪些记录、比较应用程序将更改提交到数据库前后的结果,或将其与序列中的其他查询分开运行时,重新运行 HQL 会很有用。

  1. 打开 Hibernate Debugger 日志条目 ,以重新运行所需查询。

  2. 点击 HQL 旁边的 绿色三角形图标执行查询。 如果某些参数值无法恢复,系统会提示指定这些值。

    JPA 控制台 会执行查询并显示其结果。

    从 JPA Console 中的 Hibernate Debugger 日志重新运行查询的结果
  3. (可选)使用不同的参数值重新运行查询:

    1. 从结果选项卡切换到控制台选项卡。

      详细了解 JPA Console 布局。

    2. 在查询工具栏中,点击 参数图标查看参数。 这会在控制台右侧打开一个包含参数值的窗格。

    3. 编辑参数值,然后按 Ctrl+Enter 重新运行查询。

重新运行 SQL 查询

当需要检查 Hibernate 在延迟加载期间提取了哪些记录,或慢查询直接针对数据库运行时需要多长时间时,重新运行 SQL 会很有用。

  1. 打开 Hibernate Debugger 日志条目 ,以重新运行所需查询。

  2. 点击 SQL 旁边的 绿色三角形图标执行查询。

    特定于数据库的查询控制台会执行查询, 服务工具窗口会显示结果。

    从 Services 工具窗口中的 Hibernate Debugger 日志重新运行查询的结果
  3. (可选)使用不同的参数值重新运行查询:

    1. 在编辑器中,转到 IntelliJ IDEA 打开的查询控制台标签页。 SQL 查询已在那里,并带有原始参数值。

    2. 编辑参数值,然后按 Ctrl+Enter 重新运行查询。

调试时访问数据库

当查询结果与预期不符时,原因可能不在代码中,而在数据中。 为了帮助检查二者,Hibernate Debugger 会将调试会话中的数据库连接添加到 数据库工具窗口。

Database 工具窗口显示了在调试器会话期间添加的数据源。 工具窗口中的顶层节点显示运行配置名称,数据源本身在方括号中带有调试注释。

以下是可在 IntelliJ IDEA 中使用调试会话中的 数据源 的几个示例:

Hibernate Debugger 创建的数据源会在调试会话结束时被移除。 若要永久保留数据源,请在会话仍在运行时创建其副本。

调试会话结束后保留数据源

  1. 调试会话运行时,转到 数据库 工具窗口。

  2. 查找以调试会话命名的文件夹,并选择要保留的数据源。

  3. 右键点击数据源并选择 复制/粘贴 | 复制图标 副本。

    • 或者按 Ctrl+D。

  4. 数据源和驱动程序对话框将打开。 如有需要,请重命名数据源或调整其连接详细信息。

  5. 点击 OK 以保存副本。

  6. 复制的数据源会放置在与原始数据源相同的文件夹中。 若要防止副本被移除,请右键点击它并选择 移动 | 移至顶层。

参考:Hibernate Debugger 日志条目

带有框架标记日志不同组成部分的 Hibernate Debugger 日志条目图像

Hibernate Debugger 日志条目包含以下部分:

  1. 标头

  2. 会话 ID

  3. HQL 语句

  4. SQL 语句

  5. 调用堆栈

该插件还会向调试器添加一个工具栏图标 (6): Hibernate Debugger 图标 SQL 日志设置和筛选器 ,用于筛选日志条目并更改其显示方式。

日志条目标头包含以下信息:

  1. Hibernate Debugger 捕获查询时的时间戳。 它使用带 UTC 偏移量的 ISO 8601 格式的本地时间。

  2. 执行查询所花费的时间。

  3. 执行查询所在的 Hibernate 事务 的 ID。 此值由调试器分配。 短横线表示 Hibernate Debugger 无法确定查询属于哪个事务。

    可以点击 ID 并选择 按此事务使用筛选器 ,筛选日志条目以仅显示来自此事务的查询。

会话 ID

此 ID 标识将查询发送到数据库的 Hibernate 会话。 它由 Hibernate 分配。

短横线表示 Hibernate Debugger 无法确定是哪个会话发送了查询。

HQL 语句

这是应用程序交给 Hibernate,并由 Hibernate 转换为下方 SQL 语句的查询。 在代码中,查询可以来自仓库方法、查询字符串 (HQL、JPQL、JDQL) 或 Jakarta Persistence Criteria API ,但此处始终显示为 HQL 语句。

如果 HQL 包含参数,其值会按以下格式之一列在单独一行:

  • name: Type = value :命名参数

  • ?1: Type = value :位置参数

  • __param_0: Type = value :生成的参数 (例如,派生自仓库方法名称)

  • ?unknown: Type = value :无法确定名称的参数

  • name: <unbound> :执行 HQL 时没有值的参数

绿色三角形图标执行查询 图标可使用相同的参数值 在 JPA 控制台中重新运行 HQL 语句。 如果图标带有错误指示器 (红色 X 标记 ),则表示某些参数值无法传递给控制台。 在这种情况下,控制台会在重新运行 HQL 之前提示输入缺失的值。

SQL 语句

这是 Hibernate 发送到数据库的 SQL 语句。 它可以由 Hibernate 从上方的 HQL 转换而来,由 Hibernate 自行生成,或在代码中编写为原生 SQL 查询。

如果语句包含参数,其值会显示在语句内。

绿色三角形图标执行查询 图标可使用相同的参数值 在查询控制台中重新运行 SQL 语句。

调用堆栈

调用堆栈显示了导致 Hibernate 将 SQL 语句发送到数据库的方法调用。 与任何 Java 堆栈跟踪一样,最近的调用位于顶部。 库代码中的调用 (例如 Hibernate 或 Spring) 默认处于收起状态。

调用堆栈中的每一行表示一次方法调用。 例如,请考虑这个简化的堆栈:

at com.example.library.BookRepository.findByTitle(BookRepository.java:31) at com.example.library.BookService.searchBooks(BookService.java:24) at com.example.library.BookController.listBooks(BookController.java:18)

高亮显示的行表示对 searchBooks() 的调用。 示例堆栈提供了关于它的以下详细信息:

  • searchBooks() 由 BookController.listBooks() 调用。

  • 它在 BookService 类中声明,该类属于 com.example.library 软件包。

  • 它在 BookService.java 源文件中实现。

  • 在该文件的第 24 行,它调用了 BookRepository.findByTitle()。

大多数堆栈行以文件名和行号结尾,用于显示此方法调用下一个方法的位置。 可以点击它们导航到编辑器中的该调用。 如果某一行改为以 Unknown Source 或 <generated> 结尾,则该调用通常来自框架直接以编译形式生成的代码,因此没有对应的源文件。

来自 Spring Data JPA 应用程序的示例

Invocation stack: <36 hidden frames> at com.example.library.BookRepository.findByTitle(Unknown Source) at com.example.library.BookService.searchBooks(BookService.java:24) <14 hidden frames> at com.example.library.BookService$$SpringCGLIB$$0.searchBooks(<generated>) at com.example.library.BookController.listBooks(BookController.java:18) <53 hidden frames>

在此示例中,调用序列如下 (从下往上阅读):

  1. 库代码中的调用链 (收起为 <53 hidden frames>) 导致项目代码中调用了 BookController.listBooks()。

  2. BookController.listBooks() 调用了 BookService.searchBooks()。

    1. 调用进入 BookService$$SpringCGLIB$$0。 这是 Spring 在运行时生成的代理,因此显示 <generated> 而不是文件名。

    2. 该代理启动了 Spring 库代码中的调用链 (收起为 <14 hidden frames> ),最终调用了 BookService.searchBooks()。

  3. BookService.searchBooks() 调用了 BookRepository.findByTitle()。

    调用进入 Spring Data 提供的方法实现。 此实现是在运行时生成的,因此显示 Unknown Source 而不是文件名。

  4. findByTitle() 的实现启动了 Spring 和 Hibernate 库代码中的调用链 (收起为 <36 hidden frames> ),最终导致 Hibernate 将 SQL 语句发送到数据库。

设置和筛选器

条目

描述

记录数据库查询日志

开启或关闭查询日志记录。

有关更多信息,请参见 停止记录查询。

语句格式设置

更改语句在调试器控制台中的显示方式:

  • 对于 HQL 语句,这会将每个子句 (例如 select、 从 或 where) 移到新行,并将生成的别名替换为实体的首字母。

  • 对于 SQL 语句,这会应用 IDE 中配置的 SQL 代码样式。

仅显示疑似 N+1 查询

仅显示来自疑似存在 N+1 问题的事务的查询,即同一查询会被反复执行。

有关更多信息,请参见 识别 N+1 查询并在代码中跟踪其来源。

按时长筛选

指定最短持续时间 (毫秒),以仅显示执行时间达到或超过此时长的查询。

按事务使用筛选器

指定事务 ID,以仅显示在此事务中执行的查询。

2026年 11月 3日