人们在使用 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 方言”),但您可能仍然感觉“不对”,尤其是当您稍后必须再次编辑查询时。