在项目中经常需要整理数据库表结构文档。一般情况下都是手动整理数据库表结构设计文档,当表结构有变动的时候,随时自己手动维护。数据库表多了之后,手动整理和维护数据库表结构文档的工作量会非常大,非常单调,还非常容易出错。
有没有什么类似 Swagger 那样好用的工具帮助我们自动生成数据库表结构文档呢?答案是:有。
感谢国内能干的工程师开源了一款数据库表结构文档自动生成工具—— Screw 。
43.1 Screw 项目概述
Screw 的项目地址是 https://github.com/pingfangushi/screw
下面是作者关于这个开源项目的说明(真是和我们的感觉很像):
在企业级开发中、我们经常会有编写数据库表结构文档的时间付出,从业以来,待过几家企业,关于数据库表结构文档状态:要么没有、要么有、但都是手写、后期运维开发,需要手动进行维护到文档中,很是繁琐、如果忘记一次维护、就会给以后工作造成很多困扰、无形中制造了很多坑留给自己和后人,于是萌生了要自己写一个插件工具的想法
关于名字,想一个太难了,好在我这个聪明的小脑瓜灵感一现,怎么突出它的小,但重要呢?从小就学过雷锋的螺丝钉精神,摘自雷锋日记:虽然是细小的螺丝钉,是个细微的小齿轮,然而如果缺了它,那整个的机器就无法运转了,慢说是缺了它,即使是一枚小螺丝钉没拧紧,一个小齿轮略有破损,也要使机器的运转发生故障的…,感觉自己写的这个工具,很有这意味,虽然很小、但是开发中缺了它还不行,于是便起名为screw(螺丝钉)。
根据作者的说明,Screw 有如下的特点
- 简洁轻量、设计良好,代码量很少。
- 支持多数据库。
- 可生成多种格式文档。
- 能够灵活扩展。
- 支持自定义模板。
43.3 编写代码生成数据库文档
43.3.1 概要说明
生成数据库文档的代码逻辑很简单,只需要经过下面 5 步:
- 设置数据源
- 设置生成文档的参数
- 设置文档处理规则
- 构造 Screw 配置对象
- 执行生成操作
43.3.2 创建新的工程
显然,生成数据库文档的过程只和数据源有关,和任何业务应用程序都没有直接的关系。所以最好写一个独立的Spring Boot 项目来处理这个过程。不管怎么样,绝对不要把和生成数据库文档有关的代码放在正式的业务代码中。
这个工程我们可以不选任何依赖,然后生成后手工放入下面的依赖内容
你可以通过下面的地址在 mvnrepository 查询最新版本<dependency>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw-core</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>runtime</scope>
</dependency>
https://mvnrepository.com/artifact/cn.smallbun.screw/screw-core
我们先准备一个新的类,接下来本节的代码都放到这个类里面
package com.longser.db.doc;
import org.springframework.stereotype.Component;
@Component
public class DocumentMaker {
}
43.3.3 定义配置参数
首先,需要在这个类中定义如下的参数。而写参数的含义很明显,因此这里不做详细的解释。
String DOCUMENT_VERSION = "1.0.0";
String DOCUMENT_TITTLE = "数据库设计文档";
String DOCUMENT_DIRECTORY = "./doc";
@Value("${spring.datasource.driver-class-name}")
String driverClassName;
@Value("${spring.datasource.url}")
String jdbcUrl;
@Value("${spring.datasource.username}")
String jdbcUsername;
@Value("${spring.datasource.password}")
String jdbcPassword;
EngineFileType fileType = EngineFileType.HTML
在这里我们这里指定生成的文件格式为 HTML。除了 HTML 之外,screw 还支持 Word 、Markdown 这两种文件格式。作者不太建议生成 Word 格式而推荐 Markdown 格式。
43.3.4 获取数据库源
首先定义一个生成数据源的方法:
/**
* 获取数据库源
*/
private DataSource getDataSource() {
//数据源
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName(driverClassName);
hikariConfig.setJdbcUrl(jdbcUrl);
hikariConfig.setUsername(jdbcUsername);
hikariConfig.setPassword(jdbcPassword);
//设置可以获取tables remarks信息
hikariConfig.addDataSourceProperty("useInformationSchema", "true");
hikariConfig.setMinimumIdle(2);
hikariConfig.setMaximumPoolSize(5);
return new HikariDataSource(hikariConfig);
}
43.3.5 设置生成文档的参数
接下来定义一个方法设置各种生成文档的参数,主要是文档的保存路径、文档类型以及文件名:
/**
* 获取文件生成配置
*/
private EngineConfig getEngineConfig() {
//生成配置
return EngineConfig.builder()
//生成文件路径
.fileOutputDir(DOCUMENT_DIRECTORY)
//打开目录
.openOutputDir(true)
//文件类型
.fileType(fileType)
//生成模板实现
.produceType(EngineTemplateType.freemarker)
//自定义文件名称
.fileName("数据库结构文档").build();
}
如果不配置生成文件路径则会默认也存放在项目的 doc 目录下。
43.3.6 设置文档处理规则
这一步你可以 用方法 designatedTableName
指定只处理哪些表,或者用方法 ignoreTableName
定义忽略处理哪些表。
通常我们是采用忽略一部分的规则:
/**
* 获取数据库表的处理配置,可忽略
*/
private ProcessConfig getProcessConfig() {
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");
return ProcessConfig.builder()
//忽略表名
.ignoreTableName(ignoreTableName)
//忽略表前缀
.ignoreTablePrefix(ignorePrefix)
//忽略表后缀
.ignoreTableSuffix(ignoreSuffix)
.build();
}
如果你不指定 ProcessConfig 的话,就会按照默认配置来处理全部。
43.3.7 构造 Screw 配置对象
编写一个方法去构造 Screw 配置对象。这里会用到前面定义的参数或者各种配置对象
private Configuration getScrewConfig(DataSource dataSource, EngineConfig engineConfig, ProcessConfig processConfig) {
return Configuration.builder()
//版本
.version(DOCUMENT_VERSION)
//描述
.description(DOCUMENT_TITTLE)
//数据源
.dataSource(dataSource)
//生成配置
.engineConfig(engineConfig)
//生成配置
.produceConfig(processConfig)
.build();
}
43.3.8 生成数据库文档
晚上上面的工作以后,接下来把他们连贯起来执行即可:
public void generateDatabaseDocumentFile() {
// 1.获取数据源
DataSource dataSource = getDataSource();
// 2.设置生成文档的参数
EngineConfig engineConfig = getEngineConfig();
// 3. 设置文档处理规则
ProcessConfig processConfig = getProcessConfig();
// 4.构造 Screw 配置对象
Configuration config = getScrewConfig(dataSource, engineConfig, processConfig);
// 5.执行生成数据库文档
new DocumentationExecute(config).execute();
}
43.3.9 定义数据源
删除 application.properties,创建 application.yml,然后把开发项目中的数据源参数复制过来。
43.3.10 调用生成文档
把主应用程序改成如下内容
package com.longser.db.doc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MakeDatabaseDocumentApplication {
static DocumentMaker documentMaker;
@Autowired
MakeDatabaseDocumentApplication(DocumentMaker dm) {
documentMaker = dm;
}
public static void main(String[] args) {
SpringApplication.run(MakeDatabaseDocumentApplication.class, args);
documentMaker.generateDatabaseDocumentFile();
}
}
运行程序很快就能生成期望的文档。改变 fileType
的赋值,你可以先后得到下面三种不同格式的文档
43.4 配置生成数据库文档的插件
除了基于 Java 代码这种方式之外,你还可以通过 screw 提供的 Maven 插件来生成数据库文档。:
43.4.1 编写插件配置
下面是在 pom.xml 中配置插件的片段,你可以看到需要配置的内容与编写代码很相似:
<plugin>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw-maven-plugin</artifactId>
<version>1.0.5</version>
<dependencies>
<!-- HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.0</version>
</dependency>
<!--jdbc driver-->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.7.4</version>
</dependency>
</dependencies>
<configuration>
<!--username-->
<username>****</username>
<!--password-->
<password>****</password>
<!--driver-->
<driverClassName>org.mariadb.jdbc.Driver</driverClassName>
<!--jdbc url-->
<jdbcUrl>jdbc:mysql:****</jdbcUrl>
<!--生成文件类型-->
<fileType>MD</fileType>
<!--打开文件输出目录-->
<openOutputDir>true</openOutputDir>
<!--生成模板-->
<produceType>freemarker</produceType>
<!--文档名称 为空时:将采用[数据库名称-描述-版本号]作为文档名称-->
<fileName>数据库文档</fileName>
<!--描述-->
<description>数据库设计文档生成</description>
<!--版本-->
<version>${project.version}</version>
<!--标题-->
<title>数据库文档</title>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
43.4.2 编写插件配置
打开 Maven 窗口,在 screw 的上下文相关菜单中(或者双击)执行 Build
如果配置正确,你可以得到类似下面的结果
只需要 1.668秒 就定生成了我们需要的 Markdown 格式的数据库文档。
43.5 进一步的讨论
工欲善其事,必先利其器。正如我们在本章开头所说的,手工编写数据库文档是一个效率低下又容易出错的“体力活”。使用 Screw 这样的工具能够极大地提高我们工作的效率。所有有规律的、机械重复的工作都是应该交给计算机去完成。
当然,这个 Screw 还有很多可以进一步完善的地方,比如它目前还没有办法帮我们生成关于代码表(数据字典)的文档。但是,根据最新的设计规范,绝大多数的代码(包括行政区划这样的)都应该直接编写在前端,而不是保存在数据库中。所以从这个角度来说,提取代码表的功能并不需要。
Screw 提供了编写 Java 代码和配置 Maven 插件两种生成数据库文档的方法。这两种方法都是复制到项目略作修改即可工作。尤其编写 Java 代码的方法,不涉及单独配置数据源参数的内容,用起来更加方案安全。当然,如果有人能够给 Screw 套上一个 Web 界面就更理想了——在页面上填写数据源、选择文档类型后生成数据库文档下载。这样非软件工程师也能完成生成数据库文档的工作了。
版权说明:本文由北京朗思云网科技股份有限公司原创,向互联网开放全部内容但保留所有权力。