可用版本: Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

诊断

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

jOOQ 包含一个强大的诊断 SPI,可用于检测数据库交互中不同级别的问题和效率低下

  • 在 jOOQ API 级别
  • 在 JDBC 级别
  • 在 SQL 级别

就像上一节中记录的解析连接一样,此功能不依赖于在客户端应用程序中使用 jOOQ API,而是可以通过 JDBC java.sql.Connection(代理你的实际数据库连接)公开自身。

// A custom DiagnosticsListener SPI implementation
class MyDiagnosticsListener implements DiagnosticsListener {
    // Override methods here
}

然后

// Configuration is configured with the target DataSource, SQLDialect, etc. for instance Oracle.
try (Connection c = DSL.using(configuration.derive(new MyDiagnosticsListener()))
                       .diagnosticsConnection();
     Statement s = c.createStatement()) {

    // The tooManyRowsFetched() event is triggered.
    // --------------------------------------------
    // This logic does not consume the entire ResultSet. There is more than one row
    // ready to be fetched into the client, but the client only fetches one row.
    try (ResultSet rs = s.executeQuery("SELECT id, title FROM book WHERE id > 1")) {
        if (rs.next())
            System.out.println("ID: " + rs.getInt(1) + ", title: " + rs.getInt(2));
    }

    // The duplicateStatements() event is triggered.
    // ---------------------------------------------
    // The statement is the same as the previous one, apart from a different "bind variable".
    // Unfortunately, no actual bind variables were used, which may
    // 1) hint at a SQL injection risk
    // 2) can cause a lot of pressure / contention on execution plan caches and SQL parsers
    //
    // The tooManyColumnsFetched() event is triggered.
    // -----------------------------------------------
    // When iterating the ResultSet, we're actually only ever reading the TITLE column, never
    // the ID column. This means we probably should not have projected it in the first place
    try (ResultSet rs = s.executeQuery("SELECT id, title FROM book WHERE id > 2")) {
        while (rs.next())
            System.out.println("Title: " + rs.getString(2));
    }
}

此功能会产生一定的正常操作开销,因为它需要

  • 解析 SQL 语句并将它们重新呈现为规范化的 SQL。
  • 在缓存中存储有限大小的此类规范化 SQL 列表,以收集有关该缓存的统计信息。

这就是为什么它默认不活跃在所有 Connections 上,只有像上面那样显式代理连接时才会激活。 但是,使用 Settings.diagnosticsConnection,可以更改此设置。 要打开调试日志记录,请参阅 Settings.diagnosticsLogging

以下部分描述了每个单独的事件、它们如何发生,以及应该如何以及为什么应该补救它们。

反馈

您对此页面有任何反馈吗? 我们很乐意倾听!

The jOOQ Logo