jOOQ 从您的数据库生成 Java 代码,并通过其流畅的 API 让您构建类型安全的 SQL 查询。

使用 jOOQ 的绝佳理由

我们的客户将大部分时间花在他们自己的业务逻辑上。
因为 jOOQ 负责处理他们所有的 Java/SQL 基础设施问题。

数据库优先

厌倦了 ORM 驱动您的数据库模型吗?

无论您是设计新应用程序还是与您的遗留系统集成,您的数据库都拥有您最重要的资产:您的数据。

jOOQ 以 SQL 为中心。您的数据库“优先”。

类型安全的 SQL

厌倦了在生产环境中检测 SQL 语法错误吗?

SQL 是一种高度表达性和类型安全的语言,具有丰富的语法。 jOOQ 将 SQL 建模为内部 DSL,并使用 Java 编译器编译您的 SQL 语法、元数据和数据类型。

代码生成

厌倦了在 Java 代码中重命名表和列名吗?

jOOQ 从您的数据库元数据生成 Java 类。当您的代码与您的模式不同步时,您的 Java 编译器会告诉您。

活动记录

对您为 CRUD 编写的 SQL 量感到恼火吗?

jOOQ 允许您直接在活动记录上执行 CRUD 和 POJO 映射,这些活动记录也是从代码生成器生成的。

多租户

担心多模式或共享模式多租户吗?

jOOQ 允许您在运行时配置数据库模式和表覆盖,并且还支持行级安全性。

标准化

被 SQL 方言中的细微差别弄得不知所措吗?

jOOQ 执行 SQL 转换,将常见的 SQL 表达式转换为您数据库最接近的匹配项。编写可在您所有数据库上运行的 SQL。

查询生命周期

对您的 ORM 神秘的 SQL 生成感到恼火吗?

jOOQ 允许您挂钩到其 SQL 生成生命周期中,用于日志记录、事务处理、ID 生成、SQL 转换等等。

过程

对您的 ORM 缺乏对存储过程的支持感到惊讶吗?

存储过程是现代 SQL 数据库的基本功能。 jOOQ 允许您将存储函数调用嵌入到您的 SQL 语句中。

数据库优先

您的数据是您最重要的资产。

当您选择关系数据库管理系统来存储您的数据时,您做出了明智的决定。您习惯于编写 SQL 来查询和操作您的数据。现在,您正在寻找一种专业的工具来帮助您用 Java 编写 SQL。

使用 jOOQ,您的数据库和您的数据优先。您希望能够使用您的数据库提供的所有功能,使用用于与数据库交互的语言:SQL。 jOOQ 将让您准确地做到这一点。

更多详细信息可以在手册中找到

Database First

类型安全的 SQL

SQL 是一种非常独特且丰富的语言,经过优化设计,可以以简单、声明性的形式表达复杂的查询。编写 SQL 时,您将专注于您要获取的数据,而不是您希望如何获取它。

jOOQ 将 SQL 视为其本质:一种语言。通过其独特而现代的流畅 API 设计技术,jOOQ 将 SQL 作为内部领域特定语言直接嵌入到 Java 中,使开发人员可以轻松编写和阅读几乎感觉像实际 SQL 的代码。

作为内部领域特定语言,jOOQ 可以利用强大的 Java 编译器和 Java 的泛型进行

  • 列类型检查
  • 行值表达式类型检查
  • SQL 语法检查

更多详细信息可以在手册中找到

Typesafe SQL

代码生成

SQL 元数据是您的代码库的重要组成部分。您可以在其中定义表和列类型,这些类型可以以类型安全的方式在您的 SQL 语句中使用。

在开发过程中,SQL 元数据处于不断变化中。开发人员会不断添加、重命名、删除表、列、过程、参数。

使用 jOOQ 的代码生成器,您的 Java 代码不仅会根据您实际的 SQL 元数据进行编译,还会立即注意到对 SQL 元数据执行的更改。这将有助于在您的开发或部署周期的早期阶段防止由于不正确地更改元数据而导致的语法错误。

不再因更改元数据而产生生产力上的意外!

更多详细信息可以在手册中找到

Code Generation

活动记录

您每天的大部分 SQL 工作都是重复的 CRUD:创建、读取、更新、删除数据库记录。

jOOQ 通过将每个数据库表建模为类型安全的记录来整合流行的活动记录范例,该记录能够通过直观的 API 存储、删除和刷新自身。

除了上述操作之外,jOOQ 的活动记录还能够

  • 乐观锁定
  • 外键导航
  • 从/到您的自定义 POJO 类型进行映射

更多详细信息可以在手册中找到

Active Records

多租户

您已经建立了一个明确定义的开发流程。您可能正在使用

  • 开发数据库(甚至每个开发人员一个)
  • 测试数据库
  • 暂存数据库
  • 生产数据库

jOOQ 允许您轻松配置您的环境,从而允许您重写生成的 SQL 模式和表名。

更多详细信息可以在手册中找到

Multi Tenancy

标准化

每种 SQL 方言在各种明显和微妙的方式上都有所不同。这些差异包括诸如

  • SQL 语句(例如 MERGE 与 ON DUPLICATE KEY UPDATE)
  • SQL 子句(例如 Oracle CONNECT BY 与分层 CTE)
  • 内置函数(例如 NVL、COALESCE、IFNULL、CASE .. END)
  • 伪元素(例如 DUAL、SYS.DUMMY、SYSIBM.DUAL, ...)
  • 语法元素(例如派生列列表)

流行的 SQL 数据库供应商已经为他们最具创新性和最有用的 SQL 子句和函数付出了很多努力,借助 jOOQ,您可以非常轻松地使用它们。

jOOQ 从您的查询生成 AST,如果您选择了一种数据库本身不支持的语法元素,则可以将其转换为等效的 SQL 表达式。

更多详细信息可以在手册中找到

Standardisation

查询生命周期

Java 到 SQL 的集成是您业务的核心。它连接着您最重要的两个资产

  • 您的数据
  • 您的业务逻辑

您希望完全控制此接口,从而影响 SQL 呈现、变量绑定、查询执行和其他查询操作生命周期。

jOOQ 为您提供了一个丰富的 SPI 来注入自定义行为,以便管理

  • 自定义日志记录
  • 事务管理
  • 事件触发器
  • SQL 转换

Query Lifecycle

过程

越来越多的 SQL 数据库实现了某种过程语言,用于数据库内数据处理和批量操作。您甚至可以选择将关键业务逻辑移动到数据库中以提高性能、安全性或其他原因。

使用 jOOQ,存储过程和存储函数是第一类公民,如果您选择它们是。 jOOQ 代码生成器将为每个例程生成一个可调用方法。存储函数可以类型安全地嵌入到您的 SQL 语句中。

Procedures

我们的一些客户


更多客户

推荐

成千上万快乐的 jOOQ 用户不仅仅是使用 jOOQ。他们热爱 jOOQ。
使用 jOOQ,用 Java 编写 SQL 既有趣又高效。以下是我们的一些用户所说的话

使用 jOOQ 是一种乐趣,它使我们的生活更加轻松。

Ilkka Halila - Boomlagoon Ltd.

jOOQ 团队提供的支持水平非常出色。他们非常容易沟通,并在 Skype 上不到一个小时的时间内解决了我的问题。我会向任何人推荐 jOOQ 支持服务。

Paul Woodland - ABC Information Solutions Pty Ltd

感谢 jOOQ,我们可以控制我们的 SQL,这有助于控制我们的项目。

Marco Dubacher - Ergon Informatik AG

只需一行单个方法即可轻松添加 SQL 函数的功能非常棒!老实说,我们已经通过您的文档、示例和源代码来使用了,而且从来没有因为“我该怎么做……?”而困扰过您。您的博客、手册等与一个简单的库结合在一起,构成了一个很棒的产品,可以让我们*非常非常轻松地*完成一些疯狂的 SQL。

Daniel Owens - DanielSecurities

我们成功地在来自各个领域的客户的项目中部署了 jOOQ,例如建筑公司、电信或安全服务公司:jOOQ 为我们提供了必要的灵活性来满足他们不同的要求。

Gabrio Rivera - OneOverZero GmbH

示例

使用 jOOQ DSL,SQL 看起来几乎就像 Java 本身支持一样。

SELECT TITLE
FROM BOOK
WHERE BOOK.PUBLISHED_IN = 2011
ORDER BY BOOK.TITLE
create.select(BOOK.TITLE)
      .from(BOOK)
      .where(BOOK.PUBLISHED_IN.eq(2011))
      .orderBy(BOOK.TITLE)

jOOQ 还支持更复杂的 SQL 语句。获取所有作者的名和姓,以及他们在过去三年(从 2011 年起)用德语撰写的书籍数量,如果他们用德语撰写了超过五本书,并按姓氏对这些作者进行排序,并将结果限制为第二行和第三行

SELECT AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, COUNT(*)
FROM AUTHOR
JOIN BOOK ON AUTHOR.ID = BOOK.AUTHOR_ID
WHERE BOOK.LANGUAGE = 'DE'
AND BOOK.PUBLISHED > DATE '2008-01-01'
GROUP BY AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME
HAVING COUNT(*) > 5
ORDER BY AUTHOR.LAST_NAME ASC NULLS FIRST
LIMIT 2
OFFSET 1
create.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, count())
      .from(AUTHOR)
      .join(BOOK).on(AUTHOR.ID.equal(BOOK.AUTHOR_ID))
      .where(BOOK.LANGUAGE.eq("DE"))
      .and(BOOK.PUBLISHED.gt(date("2008-01-01")))
      .groupBy(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
      .having(count().gt(5))
      .orderBy(AUTHOR.LAST_NAME.asc().nullsFirst())
      .limit(2)
      .offset(1)

类型安全示例

SQL 是一种非常类型安全的语言。 jOOQ 也是如此。 jOOQ 以独特的方式尊重 SQL 的行值表达式类型安全。 jOOQ 将使用您的 Java 编译器来类型检查以下内容

谓词

jOOQ 类型检查简单的比较谓词和带有子查询的谓词。

select().from(t).where(t.a.eq(select(t2.x).from(t2));
// Type-check here: ---------------> ^^^^
select().from(t).where(t.a.eq(any(select(t2.x).from(t2)));
// Type-check here: -------------------> ^^^^
select().from(t).where(t.a.in(select(t2.x).from(t2));
// Type-check here: ---------------> ^^^^

集合运算

jOOQ 类型检查联合子查询的度和数据类型。

select(t1.a).from(t1).unionAll(select(t2.a).from(t2));
// Type-check here: ----------------> ^^^^
select(t1.a, t1.b).from(t1).union(select(t2.a, t2.b).from(t2));
// Type-check here: -------------------> ^^^^^^^^^^

一些更复杂的示例显示了对行值表达式的类型检查

SELECT * FROM t WHERE (t.a, t.b) = (1, 2)

SELECT * FROM t WHERE (t.a, t.b) OVERLAPS (date1, date2)

SELECT * FROM t WHERE (t.a, t.b) IN (SELECT x, y)

UPDATE t SET (a, b) = (SELECT x, y FROM t2 WHERE ...)

INSERT INTO t (a, b) VALUES (1, 2)
 
select().from(t).where(row(t.a, t.b).eq(1, 2));
// Type-check here: ----------------->  ^^^^
select().from(t).where(row(t.a, t.b).overlaps(date1, date2));
// Type-check here: ------------------------> ^^^^^^^^^^^^
select().from(t).where(row(t.a, t.b).in(select(t2.x, t2.y)));
// Type-check here: -------------------------> ^^^^^^^^^^
update(t).set(row(t.a, t.b), select(t2.x, t2.y).where(...));
// Type-check here: --------------> ^^^^^^^^^^
insertInto(t, t.a, t.b).values(1, 2);
// Type-check here: ---------> ^^^^

下载

The jOOQ Logo