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

动态SQL

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

在大多数情况下,表表达式列表达式条件表达式(如前几章介绍的)将被嵌入到不同的 SQL 语句子句中,就像该语句是静态 SQL 语句一样(例如,在视图或存储过程中)

create.select(
          AUTHOR.FIRST_NAME.concat(AUTHOR.LAST_NAME),
          count()
      .from(AUTHOR)
      .join(BOOK).on(AUTHOR.ID.eq(BOOK.AUTHOR_ID))
      .groupBy(AUTHOR.ID, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
      .orderBy(count().desc())
      .fetch();

然而,有趣的是将上述所有表达式视为它们本质:表达式。因此,没有任何东西可以阻止用户提取表达式并从语句外部引用它们。以下语句是完全等效的

SelectField<?>[] select = {
    AUTHOR.FIRST_NAME.concat(AUTHOR.LAST_NAME),
    count()
};
Table<?> from = AUTHOR.join(BOOK).on(AUTHOR.ID.eq(BOOK.AUTHOR_ID));
GroupField[] groupBy = { AUTHOR.ID, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME };
SortField<?>[] orderBy = { count().desc() };

create.select(select)
      .from(from)
      .groupBy(groupBy)
      .orderBy(orderBy)
      .fetch();

每个单独的表达式和表达式集合都可以被视为一个独立的实体,它可以被

  1. 动态构造
  2. 跨查询重用

动态构造在WHERE 子句(用于动态谓词构建)的情况下特别有用。例如

public Condition condition(HttpServletRequest request) {
    Condition result = noCondition();

    if (request.getParameter("title") != null)
        result = result.and(BOOK.TITLE.like("%" + request.getParameter("title") + "%"));

    if (request.getParameter("author") != null)
        result = result.and(BOOK.AUTHOR_ID.in(
            select(AUTHOR.ID).from(AUTHOR).where(
                    AUTHOR.FIRST_NAME.like("%" + request.getParameter("author") + "%")
                .or(AUTHOR.LAST_NAME .like("%" + request.getParameter("author") + "%"))
            )
        ));

    return result;
}

// And then:
create.select()
      .from(BOOK)
      .where(condition(httpRequest))
      .fetch();

动态 SQL 构建能力可能是使用像 jOOQ 提供的运行时查询模型的最大优势之一。可以动态地创建任意复杂度的查询。在上面的例子中,我们刚刚构造了一个动态的 WHERE 子句。对于任何其他子句也可以这样做,包括动态 FROM 子句(动态 JOIN),或根据需要添加额外的 WITH 子句

上面的例子使用了可选条件,这是一种将在以下章节中解释的机制。

反馈

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

The jOOQ Logo