2.Jooq代码自动生成

Jooq提供了非常简单的方式来自动生成对应的代码,就我个人的使用感触,比mybatis-plus用起来爽,下面介绍两种殊途同归的自动生成方式

  • jooq jar包生成方式
  • maven插件生成方式

I. 前期准备

在前面体验篇中介绍的是maven插件 + h2database的代码自动生成方式;本文则将数据库替换为最常见的mysql,使用姿势上差别也不会太大

1. 数据表准备

不管使用前面说的两种方式的哪一种,前提是mysql中必须存在对应的表结构,我们这里指定两个简单的表

CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(80) NOT NULL DEFAULT '' COMMENT '用户名',
  `pwd` varchar(26) NOT NULL DEFAULT '' COMMENT '密码',
  `isDeleted` tinyint(1) NOT NULL DEFAULT '0',
  `created` varchar(13) NOT NULL DEFAULT '0',
  `updated` varchar(13) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8mb4;

CREATE TABLE `money` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名',
  `money` int(26) NOT NULL DEFAULT '0' COMMENT '钱',
  `is_deleted` tinyint(1) NOT NULL DEFAULT '0',
  `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2. 数据库相关信息

数据库连接信息

spring:
  datasource:
    # 注意指定时区
    url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password:

II. 代码自动生成

本文主要介绍的是基于SpringBoot的jooq集成,本文使用 SpringBoot 2.2.1.RELEASE

1. maven插件

首先需要创建一个SpringBoot项目,在pom.xml配置文件中,借助jooq-codegen-maven来实现代码生成

一个完整的配置示例如下

<build>
    <plugins>
        <plugin>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-codegen-maven</artifactId>
            <!--下面这段不注释时,可以通过 mvn clean install 来生成代码-->
            <executions>
                <execution>
                    <id>convergence</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>

            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>8.0.18</version>
                </dependency>
            </dependencies>

            <configuration>
                <jdbc>
                    <!-- 数据库相关配置 -->
                    <driver>com.mysql.cj.jdbc.Driver</driver>
                    <url>jdbc:mysql://127.0.0.1:3306/test</url>
                    <user>root</user>
                    <password></password>
                </jdbc>

                <generator>
                    <name>org.jooq.codegen.JavaGenerator</name>

                    <database>
                        <!-- 数据库的基本信息 -->
                        <name>org.jooq.meta.mysql.MySQLDatabase</name>
                        <inputSchema>test</inputSchema>
                        <!-- 所有的表都包含进来,用于自动生成代码 -->
                        <includes>user|money</includes>
                        <excludes></excludes>
                    </database>

                    <generate>
                        <pojos>true</pojos>
                    </generate>

                    <target>
                        <!-- 自动生成的类的包名,以及路径 -->
                        <packageName>com.git.hui.boot.jooq.dao</packageName>
                        <directory>src/main/java</directory>
                    </target>

                    <strategy>
                        <matchers>
                            <tables>
                                <table>
                                    <expression>^(.*)$</expression>
                                    <tableClass>
                                        <!-- table的后缀为TB -->
                                        <transform>PASCAL</transform>
                                        <expression>$1_T_B</expression>
                                    </tableClass>
                                    <recordClass>
                                        <!-- record的后缀为PO,表示实体类 -->
                                        <transform>PASCAL</transform>
                                        <expression>$1_P_O</expression>
                                    </recordClass>
                                    <pojoClass>
                                        <!-- pojo后缀为BO,作为内部使用的简单对象-->
                                        <transform>PASCAL</transform>
                                        <expression>$1_B_O</expression>
                                    </pojoClass>
                                </table>
                            </tables>
                        </matchers>
                    </strategy>
                </generator>
            </configuration>
        </plugin>
    </plugins>
</build>

上面的配置虽然长,但是结构比较清晰,下面拆分说明一下

a. 驱动器

因为数据源是mysql,所以我们加的是如下配置,如果是其他的数据源,替换成对应的依赖即可

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.18</version>
    </dependency>
</dependencies>

b. jdbc配置

这个配置很重要,连接数据库读取表结构信息

<jdbc>
    <!-- 数据库相关配置 -->
    <driver>com.mysql.cj.jdbc.Driver</driver>
    <url>jdbc:mysql://127.0.0.1:3306/test</url>
    <user>root</user>
    <password></password>
</jdbc>

c. generate配置

generate中指定jooq相关的一些配置

<database> 标签

指定数据库基本信息,如数据库名,哪些表需要自动生成对应的代码,哪些可以排除掉

<database>
    <!-- 数据库的基本信息 -->
    <name>org.jooq.meta.mysql.MySQLDatabase</name>
    <!-- 数据库名 -->
    <inputSchema>test</inputSchema>
    <!-- 所有的表都包含进来,用于自动生成代码 -->
    <includes>user|money</includes>
    <excludes></excludes>
</database>

如果我们希望数据库中所有的表都生成对应的代码,可以在include标签中填写.*;上面的写法表示 user, money这两张表需要生成相应的代码

pojos

下面这个非必要,因为默认生成DO对象包含较多的表结构信息,所以我们可以指定生成简单的对象,用于更友好的业务传递

<generate>
    <pojos>true</pojos>
</generate>

target

自动生成类的包名以及输出地址

<target>
    <!-- 自动生成的类的包名,以及路径 -->
    <packageName>com.git.hui.boot.jooq.dao</packageName>
    <directory>src/main/java</directory>
</target>

strategy

可以给生成的表名,实体名,pojo名指定特定的后缀

<strategy>
    <matchers>
        <tables>
            <table>
                <expression>^(.*)$</expression>
                <tableClass>
                    <!-- table的后缀为TB -->
                    <transform>PASCAL</transform>
                    <expression>$1_T_B</expression>
                </tableClass>
                <recordClass>
                    <!-- record的后缀为PO,表示实体类 -->
                    <transform>PASCAL</transform>
                    <expression>$1_P_O</expression>
                </recordClass>
                <pojoClass>
                    <!-- pojo后缀为BO,作为内部使用的简单对象-->
                    <transform>PASCAL</transform>
                    <expression>$1_B_O</expression>
                </pojoClass>
            </table>
        </tables>
    </matchers>
</strategy>

代码自动生成

执行maven插件在idea中比较简单了,如下图,执行完毕之后,就可以在上面定义的路径下看到生成的类

2. jar包生成

除了上面介绍的maven插件自动生成代码之外,还可以借助jooq-xx.jar来自动生成代码,最大的好处是不需要创建项目工程,可以直接使用

这种用法需要我们下载对应的jar包,有需要的小伙伴可以到官网去获取,同时我也传了一份到百度网盘,关注微信公众号:一灰灰blog之后,回复 jooq-code-gen 即可获取下载信息(我个人不太建议使用这种方式,maven插件是真香)

下面假设各位小伙伴已经get到了所需的信息,对应的jar包和启动脚本(deploy.sh)如下

最后一个参数是我们的配置文件, mysql.xml内容和上面的基本一致,没有太多的区别

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd">
    <!-- Configure the database connection here -->
    <jdbc>
        <driver>com.mysql.jdbc.Driver</driver>
        <url>jdbc:mysql://127.0.0.1:3306/test</url>
        <user>root</user>
        <password></password>
    </jdbc>

    <generator>
        <!-- java -classpath jooq-3.12.1.jar;jooq-meta-3.12.1.jar;jooq-codegen-3.12.1.jar;reactive-streams-1.0.3.jar;mysql-connector-java-5.1.41.jar;. org.jooq.codegen.GenerationTool mysql.xml -->
        <!-- The default code generator. You can override this one, to generate your own code style.
             Supported generators:
             - org.jooq.util.JavaGenerator
             - org.jooq.util.ScalaGenerator
             Defaults to org.jooq.util.JavaGenerator -->
        <name>org.jooq.codegen.JavaGenerator</name>

        <database>
            <!-- The database marketType. The format here is:
                 org.util.[database].[database]Database -->
            <name>org.jooq.meta.mysql.MySQLDatabase</name>

            <!-- The database schema (or in the absence of schema support, in your RDBMS this
                 can be the owner, user, database name) to be generated -->
            <inputSchema>test</inputSchema>

            <!-- All elements that are generated from your schema
                 (A Java regular expression. Use the pipe to separate several expressions)
                 Watch out for case-sensitivity. Depending on your database, this might be important! -->
            <includes>
               user|money
            </includes>

            <!-- All elements that are excluded from your schema
                 (A Java regular expression. Use the pipe to separate several expressions).
                 Excludes match before includes, i.e. excludes have a higher priority -->
            <excludes></excludes>
        </database>

        <generate>
            <!-- Generation flags: See advanced configuration properties -->
            <pojos>true</pojos>
            <daos>false</daos>
        </generate>

        <target>
            <!-- The destination package of your generated classes (within the destination directory) -->
            <packageName>com.git.hui.boot.jooq.dao</packageName>

            <!-- The destination directory of your generated classes. Using Maven directory layout here -->
            <directory>../src/main/java</directory>
        </target>

        <strategy>
            <matchers>
                <tables>
                    <table>
                        <expression>^(.*)$</expression>
                        <tableClass>
                            <!-- table的后缀为TB -->
                            <transform>PASCAL</transform>
                            <expression>$1_T_B</expression>
                        </tableClass>
                        <recordClass>
                            <!-- record的后缀为PO,表示实体类 -->
                            <transform>PASCAL</transform>
                            <expression>$1_P_O</expression>
                        </recordClass>
                        <pojoClass>
                            <!-- pojo后缀为BO,作为内部使用的简单对象-->
                            <transform>PASCAL</transform>
                            <expression>$1_B_O</expression>
                        </pojoClass>
                    </table>
                </tables>
            </matchers>
        </strategy>
    </generator>
</configuration>

说明

  • 上面的生成命令,适用于mac + linux操作系统,如果是widowns的童鞋,可以把-classpath参数中的冒号换成分号

3. 小结

本文主要介绍了jooq代码自动生成的两种方式,各自的优缺点比较明显

  • maven: 简单,简洁,高效,缺点是需要依托项目来执行
  • jar包: 独立运行,缺点是需要下载配套的jar包

II. 其他

0. 项目

系列博文

源码