传统软件项目交付给客户的时候一般需要提供软件所有的设计文档,其中包括数据库设计文档。
数据库设计文档生成工具有很多,但很多时候格式不一定能满足自己项目方的要求,生成后需要自己微调,比较麻烦。
本文介绍一款基于java jdbc 的数据库表结构生成工具,代码简单, 生成文档的原始模板自己可以用word 灵活调整,自主可控,生成的文档效果如下:
源码地址: https://gitcode.com/zfj321/JdbcDocGen/
使用步骤:
1. 从git下载源码,直接导入idea
2. 修改jdbc配置:
3.直接运行GenMain.java 会在项目根目录下生成doc文档。
如何修改模板:
直接用word打开该文件,调整样式即可;如果需要增减模板字段,则还需要学习deepoove的模板语法。
原理解释:
1.直接从jdbc 的 metadata 里面提取需要的表结构信息,构造成table和 column对象,用于后续模板变量。
2. word 模板文件。
直接用了一个开源项目 deepoove.com ,可以参考该工具官网了解具体用法。
deepoove 表格模板行循环例子:
货物明细和人工费在同一个表格中,货物明细需要展示所有货物,人工费需要展示所有费用。{{goods}}
是个标准的标签,将 {{goods}}
置于循环行的上一行,循环行设置要循环的标签和内容,注意此时的标签应该使用 []
,以此来区别poi-tl的默认标签语法。同理,{{labors}}
也置于循环行的上一行。
deepoove底层依赖poi:
核心代码:
package com.mapp.db.gen.util;
import cn.hutool.core.util.BooleanUtil;
import com.mapp.db.gen.entity.ColumnInfo;
import com.mapp.db.gen.entity.DBInfo;
import com.mapp.db.gen.entity.TableInfo;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 获取数据库,表,列元数据
*/
public class MateDataUtil {
public static DBInfo getDbInfo() {
Connection connection = JdbcUtil.getConnection();
DBInfo dbInfo = new DBInfo();
DatabaseMetaData metaData = null;
try {
metaData = connection.getMetaData();
String catalog = connection.getCatalog();
String schema = connection.getSchema();
dbInfo.setDbName(catalog);
dbInfo.setDbType(metaData.getDatabaseProductName());
dbInfo.setVersion(metaData.getDatabaseProductVersion());
// 获取表信息
int i = 0;
try (ResultSet rs = metaData.getTables(catalog, schema, null, new String[]{"TABLE"})) {
while (rs.next()) {
TableInfo tableInfo = new TableInfo();
tableInfo.setTableIndex(++i);
tableInfo.setTableName(rs.getString("TABLE_NAME"));
tableInfo.setTableComment(rs.getString("REMARKS"));
// 获得主键
try (ResultSet pkRs = metaData.getPrimaryKeys(catalog, schema, tableInfo.getTableName())) {
if (pkRs != null) {
while (pkRs.next()) {
tableInfo.getPkName().add(pkRs.getString("COLUMN_NAME"));
}
}
}
// 获取列信息
try (ResultSet columnMetaRs = metaData.getColumns(catalog, null, tableInfo.getTableName(), null)) {
if (columnMetaRs != null) {
int index = 1;
while (columnMetaRs.next()) {
ColumnInfo columnInfo = new ColumnInfo();
columnInfo.setColumnName(columnMetaRs.getString("COLUMN_NAME").toUpperCase());
columnInfo.setType(columnMetaRs.getString("TYPE_NAME"));
columnInfo.setColumnLenth(String.valueOf(columnMetaRs.getInt("COLUMN_SIZE")));
columnInfo.setIsNull(columnMetaRs.getBoolean("NULLABLE") ? "true" : "false");
columnInfo.setColumnComnent(columnMetaRs.getString("REMARKS"));
columnInfo.setDefaultValue(columnMetaRs.getString("COLUMN_DEF"));
if (tableInfo.getPkName().contains(columnInfo.getColumnName())) {
columnInfo.setIsPk("true");
}
// 保留小数位数
try {
int decimal_digits = columnMetaRs.getInt("DECIMAL_DIGITS");
if (decimal_digits != 0) {
columnInfo.setDigits(String.valueOf(decimal_digits));
}
} catch (SQLException ignore) {
}
// 是否自增
try {
String auto = columnMetaRs.getString("IS_AUTOINCREMENT");
if (BooleanUtil.toBoolean(auto)) {
columnInfo.setIsAutoInc("true");
}
} catch (SQLException ignore) {
}
columnInfo.setIndex(index++);
tableInfo.getColumnInfoList().add(columnInfo);
}
}
}
dbInfo.getTableInfoList().add(tableInfo);
}
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.close(connection);
}
return dbInfo;
}
}