您可以使用本指南来了解什么是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的代码生成器:
这三个选项的生成过程始终相同。 在独立情况下,您需要手动触发生成,而使用Maven和Gradle插件将在生成过程中自动进行代码生成。
无论如何,您都需要jOOQ的代码生成器的配置文件,默认情况下,该文件名为library.xml。 看起来像这样:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration xmlns= "http://www.jooq.org/xsd/jooq-codegen-3.12.0.xsd" >
<jdbc>
<driver> com.mysql.cj.jdbc.Driver </driver>
<url> jdbc:mysql://localhost:3306/library </url>
<user> root </user>
<password></password>
</jdbc>
<generator>
<database>
<!-- database specific options: What tables to schema/tables to include or exclujde ? What type of database? etc-->
<includes> .* </includes>
</database>
<target>
<!-- The destination package of your generated classes (within the destination directory) -->
<packageName> my.startup </packageName>
<!-- The destination directory of your generated classes. Using Maven directory layout here -->
<directory> c:/dev/myproject/src/main/java </directory>
</target>
</generator>
</configuration>
如您所见,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 < Record > 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 从USERS执行一个简单的select * ,然后遍历结果行/记录,打印出用户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()
仅需很小的更改,您就可以将查询转换为select * from USERS,其中id在(:ids)中 :
Result < UsersRecord > userRecords = dslContext . selectFrom ( USERS )
. where ( USERS . ID . in ( ids ))
. fetch ();
// (for-loop over userRecords)
SQL联接
让我们看一下如何联接两个表,例如: 从用户中选择* u对u.id = p.user_id的内部联接PAYMENTS 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中删除 )或更新( 更新user设置 id = 1的 email =:email,username =:username的user = )看起来像这样:
dslContext . delete ( USERS )
. where ( USERS . ID . eq ( 1 ))
. execute ();
dslContext . update ( USERS )
. set ( USERS . USERNAME , "John Rambo" )
. set ( USERS . EMAIL , "john@rambo.com" )
. 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项目添加以下依赖项就可以做任何事情。
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-starter-jooq </artifactId>
<version> 2.2.2.RELEASE </version> <!-- or your appropriate Spring boot version -->
</dependency>
然后,您可以执行以下操作:
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采用Java优先的方法,而您(通常)通常首先编写Java类和映射。 然后,您考虑数据库(表)。
另一方面,jOOQ首先是数据库或SQL,它需要一个现有的数据库架构来进行操作并从中生成其Java类。
但是,没有什么可以阻止您在同一项目中使用这两个库 。 有关如何执行此操作的快速介绍,请参阅Thorben Janssen的精彩文章 。
jOOQ vs MyBatis
MyBatis是一种SQL模板语言,您可以在其中以XML文件形式编写SQL。 有关两者之间差异的更多信息,请查看此stackoverflow线程 。
MyBatis XML文件如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace= "org.mybatis.example.UserMapper" >
<select id= "selectUser" resultType= "User" >
select * from Users where id = #{id}
</select>
</mapper>
这使您可以执行此操作:
// sqlsessionfactory is a myBatis specific entry point
try ( SqlSession session = sqlSessionFactory . openSession ()) {
UserMapper mapper = session . getMapper ( UserMapper . class );
User user = mapper . selectUser ( 1 );
}
jOOQ与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 。
鳍
本指南只是快速的速成班,介绍jOOQ可以为您和您的项目做些什么以及如何与其他选择进行比较。 有关更多信息,请查看jOOQ课程或官方的jOOQ文档 。
如果您有任何意见或反馈,只需在下面留言。
谢谢阅读。
还有更多来自哪里
本文最初出现在https://www.marcobehler.com/guides/jooq上 ,是有关现代Java编程的一系列指南的一部分。 要查找更多指南,请访问网站或订阅新闻通讯以获取有关新发布的指南的通知: https : //bit.ly/2K0Ao4F 。