何时使用 jOOQ? 何时使用 Native SQL?

119 阅读2分钟

人们在使用 jOOQ 时经常遇到的一个疑问是决定什么时候应该使用 jOOQ API 编写“复杂”查询,什么时候应该使用本机 SQL 实现。

jOOQ官方手册中,相同功能的查询示例,例如

使用 jOOQ:

   .from(AUTHOR)
   .join(BOOK).on(AUTHOR.ID.eq(BOOK.AUTHOR_ID))
   .groupBy(AUTHOR.ID, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
   .fetch();

使用native SQL:

FROM author
JOIN book ON author.id = book.author_id
GROUP BY author.id, author.first_name, author.last_name;

在nativer SQL 情况下,请注意您仍然可以使用 jOOQ 的普通SQL模板API,最好使用 Java 文本块,因此您仍然可以从一些 jOOQ 中获益,包括:

  • 更简单的绑定值
  • 基于动态文本的 SQL 模板
  • 所有映射实用程序
  • 事务 API 或 R2DBC 支持

使用 jOOQ,你可以这样写:

ctx.fetch(
    """
    SELECT author.first_name, author.last_name, COUNT(*)
    FROM author
    JOIN book ON author.id = book.author_id
    GROUP BY author.id, author.first_name, author.last_name
    """
);

使用JOOQ的优点和缺点

首先,在任何给定环境中使用 jOOQ 都有一些明显的优点和缺点。

优点:

  • 当你的 SQL 是动态的
  • 当您必须同时支持多种方言(您的产品支持多个 RDBMS)或连续(您最终可能必须切换 RDBMS)时。一个例子说明了方言之间的许多差异:支持 SQL/JSON
  • 当你通过代码生成和映射喜欢 jOOQ 的类型安全时
  • 当您必须获取复杂的数据树时
  • 当您必须以各种方式在运行时转换 SQL
  • 当您必须再次通过代码生成绑定到存储过程和函数时
  • 当您担心 SQL 注入时
  • 当您必须导出数据时
  • 当您想对运行时 SQL 运行诊断和 linting 时

缺点:

jOOQ 偶尔会妨碍:

  • 当您使用大量公用表表达式 (CTE)和派生表进行大型静态查询时
  • 当您想在 SQL 编辑器而不是 Java IDE 中开发查询时

让我们解释一下这两项的具体含义。

  • CTE 和派生表必须在 jOOQ 中预先声明,而不是将它们嵌入到查询中。这意味着在大多数情况下,没有简单的方法来保持 jOOQ 通常的类型安全工作,并且您又回到使用字符串标识符组合查询。当查询是动态的时候,这种方式还是很强大的。但是当它是静态的时,jOOQ 可能会导致更多的可用性问题而不是解决问题。
  • 虽然完全有可能遵循测试驱动开发 (TDD)方法来纯粹用 Java 开发 jOOQ 查询,并且最好在我们在这里描述的测试容器上运行它们,但很可能您更轻松地编写您的在本地 SQL 中进行 SQL 查询,例如在Dbeaver或您选择的任何其他 SQL 编辑器中。在这种情况下,一旦它工作,您就必须将完成的查询转换为 jOOQ。我们确实提供自动翻译服务(使用“Java 方言”),但您可能仍然感觉“不对”,尤其是当您稍后必须再次编辑查询时。