Screw: A Lightweight Database Documentation Generation Tool for Multiple Databases
Screw is an open‑source, lightweight Java plugin that automatically generates database design documentation in HTML, Word, or Markdown for a wide range of databases, offering customizable templates, extensible modules, and Maven integration to streamline documentation maintenance and reduce manual effort.
Introduction
In enterprise development, writing and maintaining database schema documentation is often tedious; many projects either lack documentation or keep it manually, leading to inconsistencies and extra work. To solve this, the author created the Screw plugin, which started development in March 2020, reached an initial release in April, and was open‑sourced on June 22, 2020.
The name reflects the idea of a small but essential screw that keeps the whole machine running, inspired by a passage from Lei Feng's diary.
Features
Simple, lightweight, well‑designed
Supports multiple databases
Generates documentation in various formats (HTML, Word, Markdown)
Highly extensible
Customizable templates
Supported Databases
MySQL
MariaDB
TIDB
Oracle
SQL Server
PostgreSQL
Cache DB (since 2016)
H2 (in development)
DB2 (in development)
HSQL (in development)
SQLite (in development)
Various other Chinese databases (in development)
Document Generation Formats
HTML
Word
Markdown
Usage
Standard Method
Add Dependency
<dependency>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw-core</artifactId>
<version>${lastVersion}</version>
</dependency>Write Code
/**
* Document generation
*/
void documentGeneration() {
// Data source configuration
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");
// Enable table remarks retrieval
hikariConfig.addDataSourceProperty("useInformationSchema", "true");
hikariConfig.setMinimumIdle(2);
hikariConfig.setMaximumPoolSize(5);
DataSource dataSource = new HikariDataSource(hikariConfig);
// Engine configuration
EngineConfig engineConfig = EngineConfig.builder()
.fileOutputDir(fileOutputDir)
.openOutputDir(true)
.fileType(EngineFileType.HTML)
.produceType(EngineTemplateType.freemarker)
.fileName("CustomFileName")
.build();
// Table filtering configuration
ArrayList
ignoreTableName = new ArrayList<>();
ignoreTableName.add("test_user");
ignoreTableName.add("test_group");
ArrayList
ignorePrefix = new ArrayList<>();
ignorePrefix.add("test_");
ArrayList
ignoreSuffix = new ArrayList<>();
ignoreSuffix.add("_test");
ProcessConfig processConfig = ProcessConfig.builder()
.ignoreTableName(ignoreTableName)
.ignoreTablePrefix(ignorePrefix)
.ignoreTableSuffix(ignoreSuffix)
.build();
// Overall configuration
Configuration config = Configuration.builder()
.version("1.0.0")
.description("Database design documentation")
.dataSource(dataSource)
.engineConfig(engineConfig)
.produceConfig(processConfig)
.build();
// Execute generation
new DocumentationExecute(config).execute();
}Maven Plugin
<build>
<plugins>
<plugin>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw-maven-plugin</artifactId>
<version>${lastVersion}</version>
<dependencies>
<!-- HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.5</version>
</dependency>
<!-- MySQL driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
</dependencies>
<configuration>
<username>root</username>
<password>password</password>
<driverClassName>com.mysql.cj.jdbc.Driver</driverClassName>
<jdbcUrl>jdbc:mysql://127.0.0.1:3306/xxxx</jdbcUrl>
<fileType>HTML</fileType>
<openOutputDir>false</openOutputDir>
<produceType>freemarker</produceType>
<fileName>TestDocumentName</fileName>
<description>Database documentation generation</description>
<version>${project.version}</version>
<title>Database Document</title>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>Extension Modules
POJO Generation
The POJO generation module, built on top of Screw, can automatically create Java POJO classes from database tables, simplifying subsequent development.
Add Dependency
<dependency>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw-extension</artifactId>
<version>${lastVersion}</version>
</dependency>Write Code
/**
* POJO generation
*/
void pojoGeneration() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
hikariConfig.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/screw");
hikariConfig.setUsername("screw");
hikariConfig.setPassword("screw");
hikariConfig.addDataSourceProperty("useInformationSchema", "true");
hikariConfig.setMinimumIdle(2);
hikariConfig.setMaximumPoolSize(5);
DataSource dataSource = new HikariDataSource(hikariConfig);
ProcessConfig processConfig = ProcessConfig.builder()
.designatedTableName(new ArrayList<>())
.designatedTablePrefix(new ArrayList<>())
.designatedTableSuffix(new ArrayList<>())
.build();
PojoConfiguration config = new PojoConfiguration();
config.setPath("/cn/smallbun/screw/");
config.setPackageName("cn.smallbun.screw");
config.setUseLombok(false);
config.setDataSource(dataSource);
config.setNameStrategy(new HumpNameStrategy());
config.setProcessConfig(processConfig);
new PojoExecute(config).execute();
}FAQ
Generated document shows garbled characters? For MySQL, add ?characterEncoding=UTF-8 to the JDBC URL.
Encounter "NoSuchFieldError: VERSION_2_3_30"? Upgrade the freemarker dependency to version 2.3.30 .
Oracle driver error "java.lang.AbstractMethodError: oracle.jdbc.driver.T4CConnection.getSchema()"? Upgrade the Oracle driver to version 19.3.0.0 and add orai18n dependency.
MySQL table/column remarks missing in generated docs? Add useInformationSchema=true to the JDBC URL.
MySQL driver version too low causing "AbstractMethodError"? Upgrade to the latest MySQL driver.
Project Address
https://gitee.com/leshalv/screw
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.