jOOQ –通过java语言以最简单的形式写SQL

当下我们使用的ORM框架中,Hibernate/Mybatis占了半边天,它们都有各自的优势和使用场景。

最近发现了一个之前从来没用的ORM框架jOOQ,非常有意思,为数据处理提供了一种全新的方式。

1. jOOQ是什么

JOOQ(Java Object Oriented Query)是一个开源框架,它可以把数据库模型的基本信息,比如表名,字段名自动生成相应的Java类;并在此基础上提供了一整套数据处理的API。

Hibernate致力于以面向对象的方式处理数据,隐藏了所有SQL相关处理;Mybatis则是在XML文件中写SQL。

jOOQ与它们都不同,它致力于通过java语言以最简单的形式写SQL。使用jOOQ DSL(Domain-Specific Language), SQL看起来几乎是由Java本地支持的。

原生SQL如下:

SELECT TITLE
FROM BOOK
WHERE BOOK.PUBLISHED_IN = 2011
ORDER BY BOOK.TITLE


使用jOOQ写SQL的方式如下:

create.select(BOOK.TITLE)
      .from(BOOK)
      .where(BOOK.PUBLISHED_IN.eq(2011))
      .orderBy(BOOK.TITLE)

从mvnrepository上查询jOOQ,发现它的第一个版本早在2011年,到现在已经有9个年头了,社区依然活跃。
jOOQ之所以诞生,大概是人们厌倦了直接写SQL,用java以流式的方式写SQL,上手成本并不算高,熟练以后应该很舒服。

2. jOOQ解决了什么问题

jOOQ是将SQL语言集成到Java中的一种简单方法,它使开发人员可以直接用Java快速,安全地编写高质量的SQL,从而使他们可以专注于自己的业务。

绝大部分数据库函数,都转化为了java方法,使用起来自然方便,它还能进行必要的类型检查,规避了大多数语法错误。

它有下面这几个优势:

  • 数据库优先,它不提倡隐藏SQL;与Mybatis一样,以SQL优先,同时可以快速安全的编写SQL。
  • 类型安全的SQL,它支持列类型检查、行值表达式检查、SQL语法检查。
  • 代码自动生成,自动生成一份Model类,不需要再手动维护它们。
  • SQL标准化,各个数据库方言存在很多细微差别,jOOQ可以自动进行转换
  • 支持区分不同环境,可以动态切换开发数据库、测试数据库等不同环境的数据库
  • 查询生命周期,jOOQ不尝试隐藏SQL,围绕整个生命周期开放了接口,我们可以做日志自定义,事件触发,SQL转换等处理。
  • 支持编写存储过程

3. 更多的例子

/**  一个复杂的查询

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)

//类型检查

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: ---------------> ^^^^

//表达式类型检查

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: ---------> ^^^^

4. 小结

本文简单介绍了JOOQ以及为什么要使用它,作为一个强力的ORM框架,其从一个新的方向尝试更快更好的编写SQL,很值得我们学习。

本文并没有一步一步的写出可运行的示例,因为这个过程本身很简单,没有必要占篇幅。

当然各位也可以参考这个项目jOOQ-spring-boot-example,它是从官方示例中剥离出来的,导入IDEA后可以直接运行。


文章作者: 沉迷思考的鱼
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 沉迷思考的鱼 !
评论
 本篇
jOOQ –通过java语言以最简单的形式写SQL jOOQ –通过java语言以最简单的形式写SQL
当下我们使用的ORM框架中,Hibernate/Mybatis占了半边天,它们都有各自的优势和使用场景。 最近发现了一个之前从来没用的ORM框架jOOQ,非常有意思,为数据处理提供了一种全新的方式。 1. jOOQ是什么JOOQ(Java
2020-02-14
下一篇 
温故知新--深入理解Map 温故知新--深入理解Map
对于Java的集合认知一直以来都不够清晰,现在特地对Map做一次总结,以加深印象。 Map接口位于java.util包下,该包下一共提供了如下具体的实现类(基于JDK1.8),java.util包中开放的实现类如下图所示: 涉及的接口和
2019-11-13
  目录