【SpringBoot DB 系列】Jooq 初体验

【SpringBoot DB 系列】Jooq 初体验

【SpringBoot DB 系列】Jooq 初体验

java 环境中,说到数据库的操作,我们通常会想到的是 mybatis 或者 hibernate,今天给大家介绍一个国内可能用得不太多的操作方式 JOOQ,一款基于 Java 访问关系型数据库的工具包,轻量,简单,并且足够灵活的 ORM 框架

本文将各位小伙伴演示一下 jooq 集成 springboot 的姿势

I. 项目搭建

我们这里借助 h2dabase 来搭建演示项目,因此有兴趣的小伙伴在文末可以直接获取项目地址启动即可体验,不需要额外的安装和配置 mysql 了

本文采用SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA进行开发

1. pom 依赖

下面给出核心的依赖配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jooq</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>

2. 配置

接下来设置一下数据库相关的配置信息,在资源目录resources下,新建配置文件application.properties

#Database Configuration
spring.datasource.url=jdbc:h2:~/h2-jooq-db
spring.datasource.username=test
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver

3. 数据库初始化

jooq 有一个特点,是需要我们自己来生成表结构对象,所以我们先初始化一下 h2dabase 的数据结构,详情可以参考博文 【DB 系列 h2databse 集成示例 demo】

表结构定义文件schema-h2.sql, 请注意表结构与 mysql 的表创建姿势不太一样哦

DROP TABLE IF EXISTS poet;

CREATE TABLE poet (
  `id` int NOT NULL,
  `name` varchar(20) NOT NULL default '',
  CONSTRAINT pk_t_poet PRIMARY KEY (ID)
);

数据初始化data-h2.sql

INSERT INTO `poet` (`id`, `name`)
VALUES
	(1, '李白'),
	(2, '艾可翁'),
	(3, '敖陶孙'),
	(4, '安稹'),
	(5, '艾性夫'),
	(6, '奥敦周卿'),
	(7, '安鏖'),
	(8, '阿鲁威'),
	(9, '安鸿渐'),
	(10, '安邑坊女');

我们接下来借助 maven 插件来初始化数据, pom.xml文件中,添加如下配置

<!-- The H2 test schema is loaded here -->
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>sql-maven-plugin</artifactId>

    <executions>
        <execution>
            <id>create-database-h2</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>execute</goal>
            </goals>
        </execution>
    </executions>

    <configuration>
        <driver>org.h2.Driver</driver>
        <url>jdbc:h2:~/h2-jooq-db</url>
        <username>test</username>
        <password></password>
        <autocommit>true</autocommit>
        <srcFiles>
            <srcFile>src/main/resources/schema-h2.sql</srcFile>
            <srcFile>src/main/resources/data-h2.sql</srcFile>
        </srcFiles>
    </configuration>

    <dependencies>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.200</version>
        </dependency>
    </dependencies>
</plugin>

如下图的 case,完成数据的初始化

【SpringBoot DB 系列】Jooq 初体验

II. 体验 case

在实际开始 jooq 的 curd 之前,需要先生成对应的表结构对象,这里也是借助 maven 插件来完成

1. 代码自动生成

同样在pom.xml中添加如下配置

<plugin>
      <groupId>org.jooq</groupId>
      <artifactId>jooq-codegen-maven</artifactId>

      <executions>
          <execution>
              <id>generate-h2</id>
              <phase>generate-sources</phase>
              <goals>
                  <goal>generate</goal>
              </goals>
          </execution>
      </executions>
      <configuration>
          <jdbc>
              <!-- 数据库相关配置 -->
              <driver>org.h2.Driver</driver>
              <url>jdbc:h2:~/h2-jooq-db</url>
              <username>test</username>
              <password></password>
          </jdbc>
          <generator>
              <database>
                  <!-- 数据库的基本信息 -->
                  <name>org.jooq.meta.h2.H2Database</name>
                  <includes>.*</includes>
                  <excludes></excludes>
                  <inputSchema>PUBLIC</inputSchema>
              </database>
              <generate>
                  <deprecated>false</deprecated>
                  <instanceFields>true</instanceFields>
                  <pojos>true</pojos>
              </generate>
              <target>
                  <!-- 自动生成的类的包名,以及路径 -->
                  <packageName>com.git.hui.boot.jooq.h2</packageName>
                  <directory>src/main/java</directory>
              </target>
          </generator>
      </configuration>
  </plugin>

【SpringBoot DB 系列】Jooq 初体验

如上图的方式执行完毕之后,会得到生成的代码

2. CURD

接下来我们给出 CURD 的基本使用姿势

import static com.git.hui.boot.jooq.h2.tables.Poet.POET;

@Service
public class PoetService {

    @Autowired
    DSLContext dsl;

    public int create(int id, String author) {
        return dsl.insertInto(POET).set(POET.ID, id).set(POET.NAME, author).execute();
    }

    public PoetRecord get(int id) {
        return dsl.selectFrom(POET).where(POET.ID.eq(id)).fetchOne();
    }

    public int update(int id, String author) {
        return dsl.update(POET).set(POET.NAME, author).where(POET.ID.eq(id)).execute();
    }

    public int delete(int id) {
        return dsl.delete(POET).where(POET.ID.eq(id)).execute();
    }

    public List<PoetRecord> getAll() {
        return dsl.selectFrom(POET).fetch();
    }
}

注意上面的使用,很好理解了,基本上能愉快的写 sql,就可以愉快的使用 jooq,上面的这种链式写法,对于 sql 的阅读是非常友好的;这里的重点是DSLContext,它是JooqAutoConfiguration自动加载的,这里直接拿来使用了(关于更多的配置与多数据源的问题,后面介绍)

3. 测试 case

在 pom 中引入web依赖,设计一些基本的测试 case

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

增删改查 case

@RestController
public class PoetRest {
    @Autowired
    private PoetService poetService;

    @RequestMapping(path = "add")
    public int add(Integer id, String name) {
        return poetService.create(id, name);
    }

    @GetMapping(path = "get")
    public String get(Integer id) {
        PoetRecord record = poetService.get(id);
        return r2str(record);
    }

    @GetMapping(path = "list")
    public List<String> list() {
        List<PoetRecord> list = poetService.getAll();
        return list.stream().map(this::r2str).collect(Collectors.toList());
    }


    @GetMapping(path = "update")
    public int update(int id, String author) {
        return poetService.update(id, author);
    }

    @GetMapping(path = "del")
    public int delete(int id) {
        return poetService.delete(id);
    }


    private String r2str(PoetRecord record) {
        return record.getId() + " # " + record.getName();
    }
}

实测结果如下

【SpringBoot DB 系列】Jooq 初体验

4. 小结

到此,SpringBoot 集成 jooq 的 demo 已经完成,并提供了基础的 CURD,整体来看,集成比较简单,需要注意的是代码自动生成,我们这里是借助 maven 插件来实现代码自动生成的, 此外也可以通过官方提供的jooq-xx.jar + xml配置文件来自动生成;后面单独捞一篇博文给与介绍

从 jooq 的使用姿势来看,最大的感官就是类 sql 的链式写法,比较的直观,阅读友好;此外需要注意的是自动生成的实体PoetRecord,不要暴露出去哦,一般推荐使用 jooq 包下面的Poet来代替PoetRecord来作为 BO 对象使用,可以通过RecordMapper来实现转换,如下

public Poet getById(int id) {
    PoetRecord record = dsl.selectFrom(POET).where(POET.ID.eq(id)).fetchOne();
    RecordMapper<PoetRecord, Poet> mapper =
            dsl.configuration().recordMapperProvider().provide(POET.recordType(), POET.getClass());
    return mapper.map(record);
}

II. 其他

0. 项目

1. 一灰灰 Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现 bug 或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

【SpringBoot DB 系列】Jooq 初体验

上一篇:CSS(9)盒子模型


下一篇:H2数据库