Java-生成数据库设计文档

news2024/11/25 16:35:41

目录

  • 场景
  • screw 官网介绍
  • 接口编写

场景

在企业开发中,有些公司会要求开发人员编写数据库表结构文档,这项工作没啥技术含量而且很繁琐,每当有表发生更改时就需要维护这个文档,或者是需要交付数据库设计文档和导出数据库设计文档这类的需求,我们都可以通过 github 上的一个数据库文档生成工具 screw,快速的生成数据库设计文档,以下内容是简单介绍了下 screw 以及如何编写导出数据库设计文档的接口。

我不生产知识,我只是个知识的搬运工 ~~


screw 官网介绍

screw gitee :开源地址

在这里插入图片描述

官方文档已经详细介绍了 screw 的特点、功能以及使用,这里我也只是搬运了一下而已 ~~

screw 的特点:

  • 简洁、轻量、设计良好
  • 多数据库支持
  • 多种格式文档
  • 灵活扩展
  • 支持自定义模板

目前支持的数据库有:

  • MySQL
  • MariaDB
  • TIDB
  • Oracle
  • SqlServer
  • PostgreSQL
  • Cache DB(2016)

文档生成支持:

  • html
  • word
  • markdown

文档截图:

  • html

html

  • word

word

  • markdown

markdown

简单实现:

引入依赖

<dependency>
    <groupId>cn.smallbun.screw</groupId>
    <artifactId>screw-core</artifactId>
    <version>${lastVersion}</version>
 </dependency>

编写代码:

/**
 * 文档生成
 */
void documentGeneration() {
   //数据源
   HikariConfig hikariConfig = new HikariConfig();
   hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
   hikariConfig.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/database");
   hikariConfig.setUsername("root");
   hikariConfig.setPassword("password");
   //设置可以获取tables remarks信息
   hikariConfig.addDataSourceProperty("useInformationSchema", "true");
   hikariConfig.setMinimumIdle(2);
   hikariConfig.setMaximumPoolSize(5);
   DataSource dataSource = new HikariDataSource(hikariConfig);
   //生成配置
   EngineConfig engineConfig = EngineConfig.builder()
         //生成文件路径
         .fileOutputDir(fileOutputDir)
         //打开目录
         .openOutputDir(true)
         //文件类型
         .fileType(EngineFileType.HTML)
         //生成模板实现
         .produceType(EngineTemplateType.freemarker)
         //自定义文件名称
         .fileName("自定义文件名称").build();

   //忽略表
   ArrayList<String> ignoreTableName = new ArrayList<>();
   ignoreTableName.add("test_user");
   ignoreTableName.add("test_group");
   //忽略表前缀
   ArrayList<String> ignorePrefix = new ArrayList<>();
   ignorePrefix.add("test_");
   //忽略表后缀    
   ArrayList<String> ignoreSuffix = new ArrayList<>();
   ignoreSuffix.add("_test");
   ProcessConfig processConfig = ProcessConfig.builder()
         //指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时,将生成指定表,其余表不生成、并跳过忽略表配置	
		 //根据名称指定表生成
		 .designatedTableName(new ArrayList<>())
		 //根据表前缀生成
		 .designatedTablePrefix(new ArrayList<>())
		 //根据表后缀生成	
		 .designatedTableSuffix(new ArrayList<>())
         //忽略表名
         .ignoreTableName(ignoreTableName)
         //忽略表前缀
         .ignoreTablePrefix(ignorePrefix)
         //忽略表后缀
         .ignoreTableSuffix(ignoreSuffix).build();
   //配置
   Configuration config = Configuration.builder()
         //版本
         .version("1.0.0")
         //描述
         .description("数据库设计文档生成")
         //数据源
         .dataSource(dataSource)
         //生成配置
         .engineConfig(engineConfig)
         //生成配置
         .produceConfig(processConfig)
         .build();
   //执行生成
   new DocumentationExecute(config).execute();
}

接口编写

运行以上代码就能在指定的路径下生成数据库设计文档,但是有些需求是要导出数据库设计文档,所以这里我提供下导出这类文档的接口写法。

引入依赖:

        <!-- 实现数据库文档 -->
        <dependency>
            <groupId>cn.smallbun.screw</groupId>
            <artifactId>screw-core</artifactId>
            <version>1.0.5</version>
            <exclusions>
                <!-- 移除 Freemarker 依赖,采用 Velocity 作为模板引擎 -->
                <exclusion>
                    <groupId>org.freemarker</groupId>
                    <artifactId>freemarker</artifactId>
                </exclusion>
                <!-- 最新版screw-core1.0.5依赖fastjson1.2.73存在漏洞,移除。 -->
                <exclusion>
                    <groupId>com.alibaba</groupId>
                    <artifactId>fastjson</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

代码:

DatabaseController.java

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
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 io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Arrays;

@Slf4j
@RestController
@RequestMapping("/db")
@Api(tags = "【数据库-管理】")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@CrossOrigin(origins = "*", methods = {RequestMethod.POST, RequestMethod.GET})
public class DatabaseController {

    @Resource
    private DataSourceProperties dataSourceProperties;
    @Resource
    private HikariDataSource hikariDataSource;

    // @Value("${ignore-pre-fix}")
    private String ignorePreFix = "quartz_,gen_"; // 这里可以读取配置文件

    private static final String FILE_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator + "db-doc";
    private static final String DOC_FILE_NAME = "数据库文档";
    private static final String DOC_VERSION = "1.0.0";
    private static final String DOC_DESCRIPTION = "文档描述";

    @GetMapping({"/export-db-document"})
    @ApiOperation(value = "导出-数据库文档", produces = "application/octet-stream")
    public void exportDbDocument(@RequestParam(defaultValue = "true") @ApiParam(value = "是否删除本地文件") Boolean deleteFile,
                                 @RequestParam(value = "id", required = false) @ApiParam(value = "导出文件类型:HTML、WORD、MD", required = false) EngineFileType fileType,
                                 HttpServletResponse response) throws IOException {
        exportDbDocument(fileType, deleteFile, response);
    }

    public void exportDbDocument(EngineFileType fileOutputType, Boolean deleteFile, HttpServletResponse response) throws IOException {
        if (fileOutputType == null) {
            fileOutputType = EngineFileType.HTML;
        }
        String docFileName = DOC_FILE_NAME + "_" + IdUtil.fastSimpleUUID();
        String filePath = doExportFile(fileOutputType, docFileName);
        String downloadFileName = DOC_FILE_NAME + fileOutputType.getFileSuffix(); //下载后的文件名
        try {
            // 读取,返回
            writeAttachment(response, downloadFileName, FileUtil.readBytes(filePath));
        } finally {
            handleDeleteFile(deleteFile, filePath);
        }
    }

    /**
     * 输出文件,返回文件路径
     *
     * @param fileOutputType 文件类型
     * @param fileName       文件名, 无需 ".docx" 等文件后缀
     * @return 生成的文件所在路径
     */
    private String doExportFile(EngineFileType fileOutputType, String fileName) {
        try (HikariDataSource dataSource = buildDataSource()) {
            // 创建 screw 的配置
            Configuration config = Configuration.builder()
                    .version(DOC_VERSION)  // 版本
                    .description(DOC_DESCRIPTION) // 描述
                    .dataSource(dataSource) // 数据源
                    .engineConfig(buildEngineConfig(fileOutputType, fileName)) // 引擎配置
                    .produceConfig(buildProcessConfig()) // 处理配置
                    .build();

            // 执行 screw,生成数据库文档
            new DocumentationExecute(config).execute();

            return FILE_OUTPUT_DIR + File.separator + fileName + fileOutputType.getFileSuffix();
        }
    }

    /**
     * 创建数据源
     */
    private HikariDataSource buildDataSource() {

        /*
         * 这里要根据 yml 文件获取数据库连接的一些信息
         *
         * 多数据源的话需要注入 DynamicDataSourceProperties,从而获取连接数据库的信息,比如:
         *
         *      @Resource
         *      private DynamicDataSourceProperties dynamicDataSourceProperties;
         *
         *      String primary = dynamicDataSourceProperties.getPrimary();
         *      DataSourceProperty dataSourceProperty = dynamicDataSourceProperties.getDatasource().get(primary);
         *      从 dataSourceProperty 获取 url、username、password
         *
         * 如果没有使用多数据源则注入 DataSourceProperties,从中获取 url、username、password
         * 如果你的 username 和 password 是放在 hikari 配置下的话,则需要注入 HikariDataSource,从中获取 username、password
         */

        // 创建 HikariConfig 配置类
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setJdbcUrl(dataSourceProperties.getUrl());
        hikariConfig.setUsername(hikariDataSource.getUsername());
        hikariConfig.setPassword(hikariDataSource.getPassword());
        hikariConfig.addDataSourceProperty("useInformationSchema", "true"); // 设置可以获取 tables remarks 信息
        // 创建数据源
        return new HikariDataSource(hikariConfig);
    }

    /**
     * 创建 screw 的引擎配置
     */
    private static EngineConfig buildEngineConfig(EngineFileType fileOutputType, String docFileName) {
        return EngineConfig.builder()
                .fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径
                .openOutputDir(false) // 打开目录
                .fileType(fileOutputType) // 文件类型
                .produceType(EngineTemplateType.velocity) // 文件类型
                .fileName(docFileName) // 自定义文件名称
                .build();
    }

    /**
     * 创建 screw 的处理配置,一般可忽略
     * 指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时,将生成指定表,其余表不生成、并跳过忽略表配置
     */
    private ProcessConfig buildProcessConfig() {
        String str = StringUtils.isBlank(ignorePreFix) ? "" : ignorePreFix;
        return ProcessConfig.builder()
                .ignoreTablePrefix(Arrays.asList(str.split(","))) // 忽略表前缀
                .build();
    }


    /**
     * 返回附件
     *
     * @param response 响应
     * @param filename 文件名
     * @param content  附件内容
     */
    private  void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {
        // 设置 header 和 contentType
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        // 输出附件
        IoUtil.write(response.getOutputStream(), false, content);
    }

    private void handleDeleteFile(Boolean deleteFile, String filePath) {
        if (!deleteFile) {
            return;
        }
        FileUtil.del(filePath);
    }
}

这里要注意的就是 buildDataSource() 这个方法中需要配置 hikariConfig 有关数据库的相关信息,如果你想从配置文件中拿连接数据库的信息,这里的写法跟你配置文件数据库配置的写法有关:

比如你配置文件是这样的:

  datasource:  
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/mike_inner?characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: root

那么 buildDataSource() 方法这样写:


	@Resource
    private DataSourceProperties dataSourceProperties;

    /**
     * 创建数据源
     */
    private HikariDataSource buildDataSource() {
        // 创建 HikariConfig 配置类
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setJdbcUrl(dataSourceProperties.getUrl());
        hikariConfig.setUsername(dataSourceProperties.getUsername());
        hikariConfig.setPassword(dataSourceProperties.getPassword());
        hikariConfig.addDataSourceProperty("useInformationSchema", "true"); // 设置可以获取 tables remarks 信息
        // 创建数据源
        return new HikariDataSource(hikariConfig);
    }

如果你配置文件是这样的:

  # 数据库配置
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mike_inner?characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
    hikari:
      username: 'root'
      password: 'root'
      driver-class-name: 'com.mysql.cj.jdbc.Driver'

那么 buildDataSource() 方法这样写:


	@Resource
    private DataSourceProperties dataSourceProperties;
	@Resource
    private HikariDataSource hikariDataSource;

    /**
     * 创建数据源
     */
    private HikariDataSource buildDataSource() {
        // 创建 HikariConfig 配置类
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setJdbcUrl(dataSourceProperties.getUrl());
        hikariConfig.setUsername(hikariDataSource.getUsername());
        hikariConfig.setPassword(hikariDataSource.getPassword());
        hikariConfig.addDataSourceProperty("useInformationSchema", "true"); // 设置可以获取 tables remarks 信息
        // 创建数据源
        return new HikariDataSource(hikariConfig);
    }

如果你配置文件是这样的:

  datasource:
    dynamic: # ??????
      primary: master
      datasource:
        master:
          name: ry-vue
          url: jdbc:mysql://127.0.0.1:3306/mike_inner?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
          driver-class-name: com.mysql.jdbc.Driver
          username: root
          password: root

那么 buildDataSource() 方法这样写:


	@Resource
    private DynamicDataSourceProperties dynamicDataSourceProperties;

    /**
     * 创建数据源
     */
    private HikariDataSource buildDataSource() {
        // 获得 DataSource 数据源,目前只支持首个
        String primary = dynamicDataSourceProperties.getPrimary();
        DataSourceProperty dataSourceProperty = dynamicDataSourceProperties.getDatasource().get(primary);
        // 创建 HikariConfig 配置类
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setJdbcUrl(dataSourceProperty.getUrl());
        hikariConfig.setUsername(dataSourceProperty.getUsername());
        hikariConfig.setPassword(dataSourceProperty.getPassword());
        hikariConfig.addDataSourceProperty("useInformationSchema", "true"); // 设置可以获取 tables remarks 信息
        // 创建数据源
        return new HikariDataSource(hikariConfig);
    }

测试:

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/765807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8月|龙讯旷腾高性能计算与工业材料模拟论坛2023

2023年8月25日 山东青岛 高性能计算与工业材料模拟论坛2023 青岛&#xff0c;别称岛城&#xff0c;国务院批复确定的中国沿海重要中心城市和滨海度假旅游城市&#xff0c;国家历史文化名城、中国帆船之都、世界啤酒之城、联合国电影之都&#xff0c;也是国家海洋科研和教育中…

【产品经理】TO B市场分析

市场分析是一个独立而又宏大的学科领域&#xff0c;并且具体使用中&#xff0c;目标和个体不同&#xff0c;分析的方式方法也不同。TO B产品的市场分析是对市场环境、市场规模、性质、特征、竞品进行分析&#xff0c;从而寻找和研究潜在需求的市场机会&#xff0c;帮助产品经理…

设计模式大白话——工厂模式

文章目录 设计模式大白话——工厂模式1.1、简单工厂:1.2、工厂方法1.3、抽象工厂 设计模式大白话——工厂模式 1.1、简单工厂: 场景与思路 ​ 现在需要开一个 Pizza 店&#xff0c;Pizza 店可以生产各种口味的 Pizza ​ 既然要生产各种各样的 Pizza&#xff0c;那就会很容易想…

管理类联考——英语——趣味篇——不择手段——d开头单词

&#x1f3e0;个人主页&#xff1a;fo安方的博客✨ &#x1f482;个人简历&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;考取过HCIE Cloud Computing、CCIE Security、CISP、RHCE、CCNP RS、PEST 3等证书。&#x1f433; &#x1f495;兴趣爱好&#xff1a;b站天天刷&…

SignalTap II 软件使用步骤

文章目录 前言一、SignalTap II是什么&#xff1f;二、使用步骤三、总结四、参考资料 前言 环境&#xff1a; 1、Quartus18.1 2、板子型号&#xff1a;原子哥开拓者2(EP4CE10F17C8) 要求&#xff1a; 能够使用SignalTap II进行片上调试。 一、SignalTap II是什么&#xff1f; S…

海外媒体发稿:链游媒体发稿写作方法及优缺点解析

链游媒体发稿是一种新的媒体发布机制&#xff0c;它可以把信息准确、及时、有效地传播给大量的人&#xff0c;帮助企业实现信息的最大化传播&#xff0c;因此越来越多的公司也开始使用链游媒体发稿服务&#xff0c;本文就介绍链游媒体发稿写作的方法及小技巧。 一、链游媒体发稿…

Kubernetes Service的过程

文章目录 Kubernetes Service的实现基础内容1. 命令 ip route show table all2. DNAT3. IPVS和iptables4. Service Service的实现简述 Kubernetes Service的实现 基础内容 在了解Service之前,需要先了解一些额外的知识: 命令: ip route show table allDNATIPVS和iptables基础…

MNE脑电数据预处理

MNE 官网链接 导包 import mne import matplotlib.pyplot as plt加载数据集 不同格式数据集使用的函数不同&#xff0c;具体在官网搜索 raw mne.io.read_raw_brainvision(r"test.vhdr", preloadTrue)此语句为了画图方便 %matplotlib降采样 raw.resample(200)…

Vue3统计数值(Statistic)

可自定义设置以下属性&#xff1a; 数值的标题&#xff08;title&#xff09;&#xff0c;类型&#xff1a;string | slot&#xff0c;默认&#xff1a;‘’数值的内容&#xff08;value&#xff09;&#xff0c;类型&#xff1a;string | number&#xff0c;默认&#xff1a;…

MySql索引分类及创建索引的相关语法

1.索引分类 1.1 InnoDB中索引的分类 聚集索引与二级索引之间的B树的结构 sql语句索引执行的过程讲解 根据id查询的聚集索引效率要比二级索引高&#xff0c;故第一条sql的执行效率要高于第二条sql的执行效率。 2.索引语法 如果一个索引只关联一个字段&#xff0c;这种索引…

[虚幻引擎插件说明] DTOperateFile 使用蓝图操作文件

本插件可以在虚幻里面使用蓝图文件进行读、写、移动、复制、删除等操作。 目录 1. 节点说明 Get Stat Data – 获取文件信息 Directory Exists – 判断目录是否存在 Directory Create – 创建目录 Directory Delete – 删除目录 File Exists – 判断文件是否存在 File …

Kubernetes Dashboard部署安装

目录 Dashboard 官方文档&#xff1a;部署和访问 Kubernetes 仪表板&#xff08;Dashboard&#xff09; | Kubernetes 参考文档&#xff1a;(120条消息) K8S 安装 Dashboard_k8s 安装dashboard_tom.ma的博客-CSDN博客 扩展&#xff1a; K8S 安装 Dashboard 1、在 master …

BUFG/BUFGCE/BUFH/BUFHCE/BUFH/BUFGHCE/BUFMR/BUFMRCE/BUFR/IBUF/IBUFDS

本文对BUFG/BUFGCE/BUFH/BUFHCE简单介绍&#xff0c;便于后续查看。 原语的使用&#xff1a;在vivado中找到所要用的原语&#xff0c;直接将其实例化到设计中即可。 文章目录 BUFGBUFGCEBUFHBUFHCEBUFMRBUFRBUFMRCEIBUFIBUFDS 下图为 7 系列 FPGA 时钟架构图&#xff1a; BU…

TypeScript基础篇 - React Webpack TS 环境实战

目录 WebpackReactTS tsconfig.json src/App.tsx src/main.tsx scripts/webpack.config.js package.json scripts/template.html 一张ai生成图~ WebpackReactTS npm install react react-dom 【安装react并且安装一个react-dom】 引用时文件出现...;需要增加定义文件&a…

数据分析案例-数据分析师岗位招聘信息可视化

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

解决appium-doctor报ffmpeg cannot be found

一、下载ffmpeg安装包 https://ffmpeg.org/download.html 找到如图所示红框位置点击下载ffmpeg安装包。 二、配置ffmpeg环境变量 三、检查ffmpeg版本信息 重新管理员打开dos系统cmd命令提示符&#xff0c;输入ffmpeg查看是否出现版本信息&#xff0c;安装完好。 ffmpeg

在php中安装php_xlswriter扩展报错,找不到php_xlswriter.dll

前言&#xff1a;这里已经把下载的php_xlswriter.dll扩展放到了php安装目录的ext目录下&#xff0c;运行php -m还是报错找不到该扩展 原因&#xff1a;下载的扩展是nts的&#xff0c;而安装的php是ts的。查看当前php是nts还是ts&#xff1a; 在PHP中&#xff0c;可以利用phpin…

DWG文件怎么转图片?简单好用的转换方法分享

将CAD文件转换成图片的优势在于&#xff0c;图片文件更易于共享和传输。CAD文件通常比较大&#xff0c;而图片文件则更加轻便&#xff0c;容易通过电子邮件或者其他方式进行传输。此外&#xff0c;图片文件更易于浏览和查看。CAD文件需要特殊的软件才能打开和查看&#xff0c;而…

全志F1C200S嵌入式驱动开发(GPIO输出)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 和v3s一样,f1c200s本身的外部引脚比较少。所以这个时候,不可避免地,很多引脚的功能就会重叠在一起。这种情况下,我们就要学会取舍了。比如说,如果是学习sd卡的时候,那么spi的…

寻找下一个生成式AI独角兽,亚马逊云科技创业加速器火热来袭

生成式AI让人工智能技术又一次破圈&#xff0c;带来了机器学习被大规模采用的历史转折点。它正在掀起新一轮的科技革命&#xff0c;为人类带来前所未有的颠覆性的影响&#xff0c;而诸多创业者也应势而上&#xff0c;寻求创新机遇。生成式AI可以创造全新的客户体验、提高企业内…