likes
comments
collection
share

「Java 开发工具」什么?听说你还在为数据库文档撰写发愁?多种方式带你轻松熟练数据库文档生成框架(Screw)

作者站长头像
站长
· 阅读数 28

🙏废话不多说系列,直接开整🙏


一、简介

    Screw 是一款功能强大、易于使用的数据库文档生成工具。它旨在帮助开发人员快速、准确地获取和整理数据库的结构信息,从而提高开发效率和减少因数据库结构不清晰而导致的错误。

Screw 特点

  1. 多数据库支持:它能够处理多种主流数据库,如 MySQL、Oracle、SQL Server、PostgreSQL 、CacheDB 等,具有广泛的适用性。
  2. 丰富的文档格式:支持生成多种常见的文档格式,如 HTML、Word、Markdown 等,满足不同场景下的需求。
  3. 详细的表结构和字段信息:提供包括表名、字段名、数据类型、长度、约束条件、注释等全面而详细的信息,让开发人员对数据库结构一目了然。
  4. 可定制性:允许用户根据特定需求进行配置,例如选择要生成文档的表、过滤特定字段等。
  5. 良好的兼容性:能够与各种开发框架和环境集成,包括 Spring Boot 等,方便在项目中直接使用。

「Java 开发工具」什么?听说你还在为数据库文档撰写发愁?多种方式带你轻松熟练数据库文档生成框架(Screw)

二、两种使用方式

(0)前期准备

准备用于生成数据库文档的 两张测试数据库表,如下:

-- flyway :数据库版本更新框架日志记���表
CREATE TABLE `t_flyway_history` (
  `installed_rank` int(11) NOT NULL,
  `version` varchar(50) DEFAULT NULL,
  `description` varchar(200) NOT NULL,
  `type` varchar(20) NOT NULL,
  `script` varchar(1000) NOT NULL,
  `checksum` int(11) DEFAULT NULL,
  `installed_by` varchar(100) NOT NULL,
  `installed_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `execution_time` int(11) NOT NULL,
  `success` tinyint(1) NOT NULL,
  PRIMARY KEY (`installed_rank`),
  KEY `t_flyway_history_s_idx` (`success`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- flyway: 变更记录表
CREATE TABLE `t_flyway_test_content` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '唯一ID',
  `content` varchar(256) DEFAULT '' COMMENT '字符内容',
  `version` bigint(20) DEFAULT '0' COMMENT '版本号',
  `create_by` varchar(25) DEFAULT '' COMMENT '创建人',
  `update_by` varchar(25) DEFAULT '' COMMENT '修改人',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COMMENT='测试表';

(1)独立的 maven 项目

【1】引入核心依赖:screw

<dependency>
    <groupId>cn.smallbun.screw</groupId>
    <artifactId>screw-core</artifactId>
    <version>1.0.5</version>
</dependency>

【1.1】 引入数据库等相关依赖

<!-- Hikari数据库连接池 也可采用阿里巴巴的Druid、C3p0等数据库连接池 -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>3.4.5</version>
</dependency>
<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.40</version>
</dependency>
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.33</version>
</dependency>

【2】完整实现代码

配置的时候注意:(前提是 数据库表注释字段注释都存在,否则生成完之后的表字段说明将为空,得重复再操作一次!)

① 配置生成表的规则是按照前缀生成还是按照指定表生成;② 是否存在需要忽略生成的表,争取一步到位;

package com.example.demo.generator;

import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import cn.smallbun.screw.core.process.ProcessConfig;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * screw 文档生成
 * <pre>
 *     使用注意事项:
 *     0. 前提:明确数据库版本信息是 MySQL5.7 还是 MySQL8.0+;
 *     1. 调整修改好 ① 数据库用户和密码;② 生成数据库文档存储的位置;③ 配置数据文档版本信息;④ 设置好数据库生成的文档名;
 *     2. 配置好需要生成的表:规则1按照前缀生成(不写前缀或者为空则视为全部生成);规则2:指定表进行生成
 * </pre>
 * @author zero
 */
public class DocumentGenerator {

    //以下static final修饰的参数 如果是基于SpringBoot项目,可以在配置文件中配置,通过@Value注解获取

    /**
     * MySQL驱动 6.0以前的使用com.mysql.jdbc.Driver,(这里演示:我这边使用的是mysql-5.7.25版本的)
     * MySQL驱动 6.0以后的使用com.mysql.cj.jdbc.Driver
     */
    private static final String Driver_Class_Name = "com.mysql.jdbc.Driver";
    /** 数据库URL   characterEncoding=UTF-8: 防止生成后文档乱码 */
    private static final String DB_URL = "jdbc:mysql://localhost:3306/zero?&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSl=false&useSSL=false";
    /**  MySQL数据库账号密码 */
    private static final String DB_USERNAME = "root";
    private static final String DB_PASSWORD = "root";
    /** 生成数据库文档文件路径 可根据本机电脑自行配置 */
    private static final String FILE_OUTPUT_DIR = "D:\\";

    /** 忽略生成的表 */
    private static final List<String> ignoreTableNameList = Arrays.asList("test_user", "test_group");
    /** 忽略生成表的前缀 */
    private static final List<String> ignorePrefixList = Arrays.asList("tb_", "test_");
    /** 忽略生成表的后缀 */
    private static final List<String> ignoreSuffixList = Arrays.asList("tb_", "test_");
    /** screw配置的文件名称,即数据库文档名称 */
    private static final String DOC_FILE_NAME = "数据库设计文档生成";
    /** screw配置的文件类型 HTML->HTML文件  WORD->WORD文件  MD->Markdown文件 */
    private static final EngineFileType FILE_OUTPUT_TYPE = EngineFileType.WORD;
    /** 版本  */
    private static final String DOC_VERSION = "1.0.0";
    /** 描述  */
    private static final String DOC_DESCRIPTION = "数据库设计文档生成";

    public static void main(String[] args) {
        generatorDocument();
    }

    public static void generatorDocument() {

        //数据源  创建HikariConfig配置类
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName(Driver_Class_Name);
        hikariConfig.setJdbcUrl(DB_URL);
        hikariConfig.setUsername(DB_USERNAME);
        hikariConfig.setPassword(DB_PASSWORD);
        //#设置useInformationSchema 可以获取tables表注释信息 即解决数据库表和列字段有说明、生成文档没有说明
        hikariConfig.addDataSourceProperty("useInformationSchema", "true");
        hikariConfig.setMinimumIdle(2);
        hikariConfig.setMaximumPoolSize(5);
        DataSource dataSource = new HikariDataSource(hikariConfig);

        //创建screw的引擎配置
        EngineConfig engineConfig = EngineConfig.builder()
                .fileOutputDir(FILE_OUTPUT_DIR)//生成文件路径
                .openOutputDir(true)//打开目录
                .fileType(FILE_OUTPUT_TYPE)//文件类型  HTML->HTML文件  WORD->WORD文件  MD->Markdown文件
                .produceType(EngineTemplateType.freemarker)//生成模板实现
                .fileName(DOC_FILE_NAME + System.currentTimeMillis())//自定义文件名称,即数据库文档名称
                .build();

        // 需要生成数据库文档的表  如果designatedTablePrefix设置值不为空,则 designatedTableName 中的表名要去掉前缀,不然会重复生成,并且表名和字段注释有误
        ArrayList<String> designatedTableName = new ArrayList<>();
        //designatedTableName.add("user");
        //designatedTableName.add("product");
        // 需要生成数据库文档的表前缀
        ArrayList<String> designatedTablePrefix = new ArrayList<>();
        designatedTablePrefix.add("t_");

        //指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时,将生成指定表,其余表不生成、并跳过忽略表配置
        ProcessConfig processConfig = ProcessConfig.builder()
                .designatedTableName(designatedTableName)//根据名称指定表生成
                .designatedTablePrefix(designatedTablePrefix)//根据表前缀生成
                .designatedTableSuffix(new ArrayList<>())//根据表后缀生成
                .ignoreTableName(ignoreTableNameList)//忽略表名
                .ignoreTablePrefix(ignorePrefixList)//忽略表前缀
                .ignoreTableSuffix(ignoreSuffixList)//忽略表后缀
                .build();
        //创建screw的配置
        Configuration config = Configuration.builder()
                .version(DOC_VERSION)//版本
                .description(DOC_DESCRIPTION)//描述
                .dataSource(dataSource)//数据源
                .engineConfig(engineConfig)//生成配置
                .produceConfig(processConfig)//生成配置
                .build();
        //执行screw,生成数据库文档
        new DocumentationExecute(config).execute();
    }
}

实现结果展示:

「Java 开发工具」什么?听说你还在为数据库文档撰写发愁?多种方式带你轻松熟练数据库文档生成框架(Screw)

(2)Spring Boot 项目整合 screw 框架

【1】引入依赖

相关的引入依赖类似 上方,完整全部的引入依赖如下:

<!-- 【核心】数据库文档生成框架 screw -->
<dependency>
    <groupId>cn.smallbun.screw</groupId>
    <artifactId>screw-core</artifactId>
    <version>1.0.5</version>
</dependency>

<!-- Hikari数据库连接池 也可采用阿里巴巴的Druid、C3p0等数据库连接池 -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>3.4.5</version>
</dependency>
<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.40</version>
</dependency>
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.33</version>
</dependency>

【2】配置 screw 相关参数

两种文件不同的设置格式:① application.properties 文件格式(本文实例操作使用这种);② application.yml 配置文件格式;

server.port = 8077

spring.datasource.name=zero
spring.datasource.url=jdbc:mysql://localhost:3306/zero?&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSl=false&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.xa.properties.useInformationSchema=true
# 生成数据库文档文件路径
FILE_OUTPUT_DIR=D:\\
# 版本
DOC_VERSION=1.0.0
# screw配置的文件名称,即数据库文档名称
DOC_FILE_NAME=ZERO数据库设计文档
# 描述
DOC_DESCRIPTION=数据库设计文档生成

转换地址:在线yaml转properties-在线properties转yaml-ToYaml.comwww.toyaml.com/

【3】代码实现

① 接口定义GeneratorDbService.java
package com.example.demo.service;

/**
 * 生成数据库文档
 */
public interface GeneratorDbService {
    /**
     * 生成 数据库表结构文档
     */
    void generatorDocument();
}

② 接口实现GeneratorDbServiceImpl.java
package com.example.demo.service.impl;

import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import cn.smallbun.screw.core.process.ProcessConfig;
import com.example.demo.service.GeneratorDbService;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.util.ArrayList;

/**
 * 生成代码实现类
 */
@Service
public class GeneratorDbServiceImpl implements GeneratorDbService {
    @Autowired
    private ApplicationContext applicationContext;//注入应用上下文

    /**
     * MySQL驱动
     */
    @Value("${spring.datasource.driver-class-name}")
    private String Driver_Class_Name;
    /**
     * 数据库URL   characterEncoding=UTF-8: 防止生成后文档乱码
     */
    @Value("${spring.datasource.url}")
    private String DB_URL;
    /**
     * MySQL数据库账号密码
     */
    @Value("${spring.datasource.username}")
    private String DB_USERNAME = "root";
    @Value("${spring.datasource.password}")
    private String DB_PASSWORD = "root";

    /**
     * 生成数据库文档文件路径 可根据本机电脑自行配置
     */
    @Value("${FILE_OUTPUT_DIR}")
    private String FILE_OUTPUT_DIR;

    /**
     * 版本
     */
    @Value("${DOC_VERSION}")
    private String DOC_VERSION;

    /**
     * screw配置的文件类型 HTML->HTML文件  WORD->WORD文件  MD->Markdown文件
     */
    private static final EngineFileType FILE_OUTPUT_TYPE = EngineFileType.WORD;
    /**
     * screw配置的文件名称,即数据库文档名称
     */
    @Value("${DOC_FILE_NAME}")
    private String DOC_FILE_NAME;
    /**
     * 描述
     */
    @Value("${DOC_DESCRIPTION}")
    private String DOC_DESCRIPTION;

    /**
     * 生成 数据库表结构文档
     */
    @Override
    public void generatorDocument() {
        //获取数据源  创建HikariConfig配置类
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName(Driver_Class_Name);
        hikariConfig.setJdbcUrl(DB_URL);
        hikariConfig.setUsername(DB_USERNAME);
        hikariConfig.setPassword(DB_PASSWORD);
        //#设置useInformationSchema 可以获取tables表注释信息 即解决数据库表和列字段有说明、生成文档没有说明
        hikariConfig.addDataSourceProperty("useInformationSchema", "true");
        hikariConfig.setMinimumIdle(2);
        hikariConfig.setMaximumPoolSize(5);
        DataSource dataSource = new HikariDataSource(hikariConfig);

        //创建screw的引擎配置
        EngineConfig engineConfig = EngineConfig.builder()
                //生成文件路径
                .fileOutputDir(FILE_OUTPUT_DIR)
                //打开目录
                .openOutputDir(true)
                //文件类型  HTML->HTML文件  WORD->WORD文件  MD->Markdown文件
                .fileType(FILE_OUTPUT_TYPE)
                //生成模板实现
                .produceType(EngineTemplateType.freemarker)
                //自定义文件名称,即数据库文档名称
                .fileName(DOC_FILE_NAME).build();

        //创建screw的配置:生成文档配置(包含以下自定义版本号、描述等配置连接)
        Configuration config = Configuration.builder()
                //版本
                .version(DOC_VERSION)
                //描述
                .description(DOC_DESCRIPTION)
                //数据源
                .dataSource(dataSource)
                //生成配置
                .engineConfig(engineConfig)
                //生成配置
                .produceConfig(getProcessConfig())
                .build();
        //执行screw,生成数据库文档
        new DocumentationExecute(config).execute();
    }

    /**
     * 配置想要生成的表、想要忽略的表
     */
    private ProcessConfig getProcessConfig() {

        //创建screw的处理配置,可忽略
        //忽略表
        ArrayList<String> ignoreTableName = new ArrayList<>();
        ignoreTableName.add("test_user");
        ignoreTableName.add("test_group");
        //忽略表前缀,如忽略test_开头的数据库表
        ArrayList<String> ignorePrefix = new ArrayList<>();
        ignorePrefix.add("test_");
        //忽略表后缀
        ArrayList<String> ignoreSuffix = new ArrayList<>();
        ignoreSuffix.add("_test");

        // 需要生成数据库文档的表  如果designatedTablePrefix设置值不为空,则 designatedTableName 中的表名要去掉前缀,不然会重复生成,并且表名和字段注释有误
        ArrayList<String> designatedTableName = new ArrayList<>();
        //designatedTableName.add("user");
        //designatedTableName.add("product");
        // 需要生成数据库文档的表前缀
        ArrayList<String> designatedTablePrefix = new ArrayList<>();
        designatedTablePrefix.add("");

        //指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时,将生成指定表,其余表不生成、并跳过忽略表配置
        ProcessConfig processConfig = ProcessConfig.builder()
                //根据名称指定表生成
                //.designatedTableName(new ArrayList<>())
                .designatedTableName(designatedTableName)
                //根据表前缀生成
                //.designatedTablePrefix(new ArrayList<>())
                .designatedTablePrefix(designatedTablePrefix)
                //根据表后缀生成
                .designatedTableSuffix(new ArrayList<>())
                //忽略表名
                .ignoreTableName(ignoreTableName)
                //忽略表前缀
                .ignoreTablePrefix(ignorePrefix)
                //忽略表后缀
                .ignoreTableSuffix(ignoreSuffix).build();
        return processConfig;
    }
}
③ 定义前端调用接口

当然,这个接口你是可以调整参数来控制是生成 word 还是 HTML 文档的格式,另外,你也可以使用 前端页面的方式来实现界面化操作。

package com.example.demo.controller;

import com.example.demo.service.GeneratorDbService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/generator")
public class GeneratorDbController {
    @Autowired
    private GeneratorDbService generatorDbService;

    /**
     * 生成数据库表结构文档
     */
    @RequestMapping("/generatorDocument")
    public void generatorDocument() {
        generatorDbService.generatorDocument();
    }
}
④ 测试接口

请求接口地址:http://localhost:8077/generator/generatorDocument

附录


🙏至此,非常感谢阅读🙏

转载自:https://juejin.cn/post/7399827379052216372
评论
请登录