可用版本: 开发版 (3.21) | 最新版 (3.20) | 3.19 | 3.18 | 3.17 | 3.16

DSL API

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

DSL API 是在 jOOQ 中构造查询或查询部分的主要方式。有关与 jOOQ 查询对象模型交互的另一种方式,请参阅模型 API

jOOQ 附带了自己的 DSL(或领域特定语言),它在 Java 中模拟 SQL。这意味着,您可以编写 SQL 语句,几乎就像 Java 本身原生支持它一样,就像 .NET 的 C# 通过 LINQ to SQL 一样。

这是一个例子来说明这意味着什么

-- Select all books by authors born after 1920,
-- named "Paulo" from a catalogue:
SELECT *
  FROM author a
  JOIN book b ON a.id = b.author_id
 WHERE a.year_of_birth > 1920
   AND a.first_name = 'Paulo'
 ORDER BY b.title
Result<Record> result =
create.select()
      .from(AUTHOR.as("a"))
      .join(BOOK.as("b")).on(a.ID.eq(b.AUTHOR_ID))
      .where(a.YEAR_OF_BIRTH.gt(1920)
      .and(a.FIRST_NAME.eq("Paulo")))
      .orderBy(b.TITLE)
      .fetch();

我们将在关于别名表的部分中了解别名是如何工作的

许多其他框架都有类似的 API 和类似的功能集。然而,jOOQ 的特别之处在于它使用非正式的 BNF 符号建模了一个统一的 SQL 方言,适用于许多特定于供应商的方言,并将该 BNF 符号实现为 Java 中的接口层次结构。当将 jOOQ 与 IDE 语法自动完成一起使用时,这个概念非常强大。您不仅可以更快地编写代码,而且您的 SQL 代码将在一定程度上进行编译时检查。这里给出了一个等同于前一个查询的 DSL 查询示例

DSLContext create = DSL.using(connection, dialect);
Result<?> result = create.select()
                         .from(AUTHOR)
                         .join(BOOK).on(BOOK.AUTHOR_ID.eq(AUTHOR.ID))
                         .fetch();

与其他使用 "流畅 API""方法链" 的更简单的框架不同,jOOQ 基于 BNF 的接口层次结构将不允许错误的查询语法。例如,以下内容将无法编译

DSLContext create = DSL.using(connection, dialect);
Result<?> result = create.select()
                         .join(BOOK).on(BOOK.AUTHOR_ID.eq(AUTHOR.ID))
                      //  ^^^^ "join" is not possible here
                         .from(AUTHOR)
                         .fetch();

Result<?> result = create.select()
                         .from(AUTHOR)
                         .join(BOOK)
                         .fetch();
                      //  ^^^^^ "on" is missing here

Result<?> result = create.select(rowNumber())
                      //         ^^^^^^^^^ "over()" is missing here
                         .from(AUTHOR)
                         .fetch();

Result<?> result = create.select()
                         .from(AUTHOR)
                         .where(AUTHOR.ID.in(select(BOOK.TITLE).from(BOOK)))
                      //                     ^^^^^^^^^^^^^^^^^^
                      // AUTHOR.ID is of type Field<Integer> but subselect returns Record1<String>
                         .fetch();

Result<?> result = create.select()
                         .from(AUTHOR)
                         .where(AUTHOR.ID.in(select(BOOK.AUTHOR_ID, BOOK.ID).from(BOOK)))
                      //                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                      // AUTHOR.ID is of degree 1 but subselect returns Record2<Integer, Integer>
                         .fetch();

反馈

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

The jOOQ Logo