您可以使用本指南来了解什么是jOOQ,如何快速入门,以及jOOQ如何与Spring和Hibernate之类的库集成或比较。
什么是jOOQ?
jOOQ是一个流行的Java数据库库,它可以让您用Java编写类型安全的SQL查询。它是如何工作的?
-
您可以使用jOOQ的代码生成器连接到数据库并生成为数据库表和列建模的Java类。
-
与其使用简单的JDBC编写SQL String语句,不如使用这些生成的Java类编写SQL查询。
-
jOOQ可以方便地将这些Java类和查询转换为真实的SQL,对数据库执行它们并将结果映射回Java代码。
当然,这只是非常高级的概述。如果您想更详细地了解jOOQ的工作原理,请继续阅读。
jOOQ:速成课程
首先:您的数据库,然后:您的Java类
与其他流行的库(例如Hibernate)相比,jOOQ采用数据库优先或以SQL为中心的方法。
使用Hibernate,您通常通常首先开始编写Java类,然后让Hibernate或类似Liquibase或Flyway的工具生成相应的数据库表。
使用jOOQ,您可以从数据库开始。您的数据库和表必须已经存在,然后使用jOOQ的代码生成器为您生成Java类。
使用jOOQ的代码生成器
您可以通过三种方式使用jOOQ的代码生成器:
-
独立版本:您需要从其网站下载 jOOQ。
-
Maven和jOOQ:使用jOOQ的Maven插件生成代码。
-
Gradle和jOOQ:您可以使用jOOQ的Gradle插件生成代码。
这三个选项的生成过程始终相同。在独立情况下,您需要手动触发生成,而使用Maven和Gradle插件将在生成过程中自动进行代码生成。
无论如何,您都需要jOOQ的代码生成器的配置文件,默认情况下,该文件名为library.xml。看起来像这样:
com.mysql.cj.jdbc.Driver
jdbc:mysql://localhost:3306/library
root
.*
my.startup
c:/dev/myproject/src/main/java
如您所见,library.xml配置文件大致可归结为:
-
您的数据库网址,用户名和密码。
-
选项,如模式生成中要包括/排除的表。
-
将生成的类放在哪里。
例:
假设您的数据库有一个USERS表。使用生成器配置运行代码生成器将创建(以及许多其他)两个类:
-
一个my.startup.Users类,代表您的Users 数据库表。
-
一个my.startup.UsersRecord类,代表您的Users表内的一行。
让我们看看如何使用这些生成的类执行SQL查询:
jOOQ的DSL
jOOQ有两个类,DSL和DSLContext(特定于域的语言),开发人员需要使用它们来开始编写SQL查询。您也可以将这些DSL类称为SQL Builder类,因为它们使您可以构建SQL查询。
由于jOOQ只是JDBC的包装,因此Java数据库基础适用,并且您需要获得数据库连接才能使jOOQ正常工作。您可以自己打开一个,或要求连接池给您一个。
让我们看一下使用Java的DriverManager的jOOQ DSL示例。
import static my.startup.Tables.*;
public class Main {
public static void main(String[] args) {
String userName = "root";
String password = "";
String url = "jdbc:mysql://localhost:3306/myhotstartup";
try (Connection conn = DriverManager.getConnection(url, userName, password)) {
DSLContext create = DSL.using(conn, SQLDialect.MYSQL);
Result result = create.select().from(USERS).fetch();
for (Record r : result) {
Integer id = r.getValue(USERS.ID);
String username = r.getValue(USERS.USERNAME);
String email = r.getValue(USERS.EMAIL);
System.out.println("ID: " + id + " + email: " + email );
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
这里发生了什么事?
- 您使用纯JDBC打开数据库连接。 这是标准的Java。您创建了jOOQ的DSLContext,可以对数据库执行查询。您执行一个简单的从用户中选择*使用jOOQ,然后遍历结果行/记录,打印出用户ID和电子邮件。
而已。
jOOQ和CRUD查询
本简短指南无法为您提供每种可能的jOOQ查询的全面解释,因此让我们看一些简单的常见查询以获得基本的了解。
请记住,jOOQ查询的读取几乎与相应的SQL查询完全一样,因此,如果没有强大的SQL技能,您会遇到问题。
SQL选择在哪里
要从id =:id的USERS中执行简单的选择*,您将执行以下查询:
UsersRecord record = dslContext.selectFrom(USERS)
.where(USERS.ID.eq(id))
.fetchAny();
// do something with record.getEmail()
只需很小的更改,您就可以将查询转换为从*用户中选择*,其中id((:ids):
Result userRecords = dslContext.selectFrom(USERS)
.where(USERS.ID.in(ids))
.fetch();
// (for-loop over userRecords)
SQL 联接
让我们看一下如何连接两个表,例如:从*用户中选择* u内部加入u.id = p.user_id上的付款p:
Result> result = dslContext.select()
.from(USERS.join(PAYMENTS)
.on(PAYMENTS.USER_ID.eq(USERS.ID)))
.fetch();
// (for-loop over join records)
SQL更新和删除
最后,删除(从id = 1的USERS中删除)或更新(更新用户设置电子邮件=:电子邮件,用户名=:用户名,其中ID = 1)如下所示:
dslContext.delete(USERS)
.where(USERS.ID.eq(1))
.execute();
dslContext.update(USERS)
.set(USERS.USERNAME, "John Rambo")
.set(USERS.EMAIL, "[email protected]")
.where(USERS.ID.eq(1))
.execute();
摘要
现在您可能已经了解了为什么jOOQ会自己调用类型安全的数据库库。它使您可以编写类似于SQL的Java代码。利用您生成的DSL的好处,例如,用户ID必须为数字,用户名必须为字符串等。
推荐:练习jOOQ
如果您想对上述各个步骤获得更详细的说明,请
尝试一下jOOQ的创建者Lukas Eder推荐的jOOQ 视频课程。
它从jOOQ的基础知识开始,涵盖了查询,记录和dao的更多细节,最终使您不得不构建一个很小的真实的Spring Boot / jOOQ项目。
jOOQ如何与Spring集成?
没有什么可以阻止您将jOOQ与Spring结合使用。但是,jOOQ与庞大的Spring生态系统之间存在各种集成级别。
@交易集成
在Spring应用程序中,通常使用@Transactional批注定义数据库事务边界。为了使jOOQ参与这些交易,您需要做一些额外的设置工作。
Spring Boot集成
Spring Boot具有jOOQ自动配置功能,这意味着它可以为您设置DSLContext并将jOOQ与Spring的事务处理集成在一起-您无需为Spring Boot项目添加以下依赖项,就无需做任何事情。
org.springframework.boot
spring-boot-starter-jooq
2.2.2.RELEASE
然后,您可以执行以下操作:
import static my.startup.Tables.*;
@Service
public class UserService {
@Autowired
private DSLContext content;
@Transactional
public void registerUser(String email) {
UsersRecord existingRecord = dslContext.selectFrom(USERS)
.where(USERS.EMAIL.eq(email))
.fetchAny();
if (existingRecord != null) {
return false;
}
// register user etc.
}
}
-
Spring Boot为您自动创建DSLContext(取决于数据源)。
-
jOOQ将参与@Transactional界定的Spring交易。
Spring数据
当前没有用于jOOQ的本地Spring Data项目,例如Spring Data JDBC或Spring Data JPA。抱歉。
jOOQ与其他Java数据库框架相比如何?
jOOQ vs Hibernate
正如本指南开头已经提到的,两者完全不同。Hibernate采用Java优先的方法,而您(通常)通常首先编写Java类和映射。然后,您考虑数据库(表)。
另一方面,jOOQ首先是数据库或SQL,它需要一个现有的数据库架构来进行操作并从中生成Java类。
但是,没有什么可以阻止您在同一项目中使用这两个库。有关如何执行此操作的快速介绍,请参阅Thorben Janssen的精彩文章。
jOOQ vs MyBatis
MyBatis是一种SQL模板语言,您可以在其中以XML文件形式编写SQL。有关两者之间差异的更多信息,请查看此stackoverflow线程。
MyBatis XML文件如下所示:
这使您可以执行此操作:
// sqlsessionfactory is a myBatis specific entry point
try (SqlSession session = sqlSessionFactory.openSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
}
jOOQ vs QueryDSL
jOOQ和QueryDSL的功能存在一定的重叠,并且QueryDSL也可以与生成的类一起使用。上面的示例与QueryDSL相似:
// 'Q' classes are generated and let you access tables, columns etc
QUser user = QUser.user;
User john = queryFactory.selectFrom(user)
.where(user.id.eq(1))
.fetchOne();
综上所述,在基于JPA(Lucene / Mongodb / JDO)的环境中,QueryDSL通常是一个不错的选择,在基于SQL的环境中,jOOQ是更好的选择。
但是请注意,QueryDSL停滞了一段时间,目前正在进行项目接管。
也可以看一下这篇比较两篇文章的(较旧的)文章:QueryDSL与jOOQ。
Fin
本指南只是快速的速成班,介绍jOOQ可以为您和您的项目做什么以及如何与其他选择进行比较。有关更多信息,请查看jOOQ课程或官方的jOOQ文档。
如果您有任何意见或反馈,只需在下面留言。
谢谢阅读。