如何查看 jOOQ 在编译时执行的 SQL 语句?

Posted

技术标签:

【中文标题】如何查看 jOOQ 在编译时执行的 SQL 语句?【英文标题】:How can one see the SQL statements that jOOQ executes at Compile Time? 【发布时间】:2021-10-20 13:27:33 【问题描述】:

我使用 jOOQ 从表中查询/插入/更新数据。

有没有办法查看 JOOQ 在编译时执行的 SQL 语句而不是运行时日志记录?

以下答案在运行时显示它们。 How can one see the SQL statements that jOOQ executes?

此工具仅转换各种 SQL 方言。 https://www.jooq.org/translate/

【问题讨论】:

【参考方案1】:

静态评估 jOOQ 查询

虽然可以构建一些能够评估 一些 静态 jOOQ 语句的 IDE 插件,但请记住,原则上和设计上,每个 jOOQ 查询是dynamic SQL query。当你写一些简单的东西时:

Result<?> r = ctx.select(T.A, T.B).from(T).fetch();

JVM 看到的(大致)是:

Field<?> a = T.A;
Field<?> b = T.B;
Field<?>[] select =  a, b ;
SelectFromStep<?> s1 = ctx.select(select);
Table<?> t = T;
SelectWhereStep<?> s2 = s1.from(t);
Result<?> r = s2.fetch();

当然,没有人以这种方式使用 jOOQ。 The DSL was designed to produce call chains that look almost like SQL through its fluent API design。因此,您的查询看起来是静态 SQL(可以在 IDE 中评估),但事实并非如此。而且你会经常使用动态 SQL 功能,例如

Result<?> r = ctx
    .select(T.A, T.B)
    .from(T)
    // Dynamic where clause
    .where(someCondition ? T.A.eq(1) : T.B.gt(2))
    .fetch();

IDE 无法评估所有这些,包括您的所有 SPI 实现,例如 ExecuteListenerVisitListener,因此,即使它在某些情况下有效,但在其他许多情况下效果不佳.

您必须执行查询才能看到实际的 SQL(针对特定的执行)。或者,您在您的 fetch() 调用上放置一个断点,并评估在调试器中调用 fetch() 的查询对象。

潜在的实际问题

每当我看到这个问题时,我认为存在一个潜在的实际问题,这体现在这种在 Java 代码之外运行 jOOQ 查询的愿望。问题是您的代码似乎很难进行集成测试。

这不容易解决,但它提醒您,当您从头开始时,您可以使用以下方法轻松集成测试所有 SQL(无论是否为 jOOQ):

    类似testcontainers 通过分离关注点并将您的 SQL 逻辑移动到适当的层中,该层可以轻松地独立于任何其他逻辑(UI 等)进行集成测试

使用这种方法,您将能够以更好的反馈周期测试您的 jOOQ 查询,在这种情况下,您可能甚至不会考虑再次在 Java 代码之外运行 jOOQ 查询,至少在大多数情况下时间。

【讨论】:

以上是关于如何查看 jOOQ 在编译时执行的 SQL 语句?的主要内容,如果未能解决你的问题,请参考以下文章

jOOQ 是不是支持在 SQL 语句上添加名称?

[SQL] sql server中如何查看执行效率不高的语句

是否可以结合 MyBatis 和 QueryDSL/jOOQ?

sql server中如何查看执行效率不高的语句

使用 jOOQ 执行 PL/SQL 函数时的 Java 空指针

jOOQ:如何在选择查询中调用 Sql 用户定义函数