├── lib
└── lib.txt
├── .gitignore
├── doc.jpg
├── table.jpg
├── summary.jpg
├── sqljdbc42.jar
├── bin
├── start.bat
└── start.sh
├── src
└── main
│ ├── java
│ └── cn
│ │ └── enilu
│ │ └── tool
│ │ └── database
│ │ └── doc
│ │ └── generator
│ │ ├── bean
│ │ ├── Constants.java
│ │ ├── ColumnVo.java
│ │ ├── TableVo.java
│ │ └── DdgDataSource.java
│ │ ├── doc
│ │ ├── Html2DocConverter.java
│ │ └── WordGenerator.java
│ │ ├── database
│ │ ├── Oracle.java
│ │ ├── PostgreSQL.java
│ │ ├── MySQL.java
│ │ ├── SqlServer.java
│ │ ├── Mongo.java
│ │ └── Generator.java
│ │ └── Main.java
│ └── resources
│ ├── database-mongo.html
│ └── database.html
├── LICENSE
├── dist.xml
├── README.md
└── pom.xml
/lib/lib.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .idea/
3 | target/
4 | *-doc
5 | lib/*.jar
--------------------------------------------------------------------------------
/doc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enilu/database-doc-generator/HEAD/doc.jpg
--------------------------------------------------------------------------------
/table.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enilu/database-doc-generator/HEAD/table.jpg
--------------------------------------------------------------------------------
/summary.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enilu/database-doc-generator/HEAD/summary.jpg
--------------------------------------------------------------------------------
/sqljdbc42.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enilu/database-doc-generator/HEAD/sqljdbc42.jar
--------------------------------------------------------------------------------
/bin/start.bat:
--------------------------------------------------------------------------------
1 | title "database-doc-generator"
2 | cd ..
3 | set JAVA_OPTIONS=-Djava.ext.dirs="lib"
4 | set JAVA_OPTIONS2= -Dfile.encoding="UTF-8"
5 |
6 | java -classpath "%CLASSPATH%" %JAVA_OPTIONS% %JAVA_OPTIONS2% cn.enilu.tool.database.doc.generator.Main
7 |
8 | pause
9 |
10 |
--------------------------------------------------------------------------------
/bin/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SCRIPT_PATH=`readlink -f "$0"`;
4 | cd `dirname ${SCRIPT_PATH}`
5 | cd ..
6 |
7 | CP=""
8 | if [ -d target/classes ]; then
9 | CP=$CP:target/classes
10 | fi
11 |
12 | for jar in `/bin/ls -1 lib/*.jar`
13 | do
14 | CP=$CP:$jar
15 | done
16 |
17 | java -Xms256M -Xmx512M -cp $CP cn.enilu.tool.database.doc.generator.Main
18 |
--------------------------------------------------------------------------------
/src/main/java/cn/enilu/tool/database/doc/generator/bean/Constants.java:
--------------------------------------------------------------------------------
1 | package cn.enilu.tool.database.doc.generator.bean;
2 |
3 | /**
4 | *
5 | * Constants
6 | * @Author enilu
7 | * @Date 2021/4/28 10:19
8 | * @Version 1.0
9 | */
10 | public class Constants {
11 | public static final int DB_MYSQL= 1;
12 | public static final int DB_ORACLE= 2;
13 | public static final int DB_POSTGRESQL= 3;
14 | public static final int DB_SQLSERVER= 4;
15 | public static final int DB_MONGO= 5;
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 enilu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/dist.xml:
--------------------------------------------------------------------------------
1 |
4 | dist
5 |
6 | tar.gz
7 |
8 |
9 |
10 | ${project.basedir}
11 | /
12 |
13 | lib/**/*
14 | bin/**/*
15 | README*
16 |
17 |
18 |
19 |
20 |
21 |
22 | ${project.basedir}/target
23 | /lib
24 |
25 | database-doc-generator*.jar
26 |
27 |
28 |
29 | ${project.basedir}/target/classes/
30 | /
31 |
32 | database.html
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/main/java/cn/enilu/tool/database/doc/generator/bean/ColumnVo.java:
--------------------------------------------------------------------------------
1 | package cn.enilu.tool.database.doc.generator.bean;
2 |
3 | /**
4 | * ColumnVo
5 | *
6 | * @author zt
7 | * @version 2018/10/6 0006
8 | */
9 | public class ColumnVo {
10 | private String name;
11 | private String type;
12 | private String key;
13 | private String isNullable;
14 | private String comment;
15 |
16 |
17 | public String getName() {
18 | return name;
19 | }
20 |
21 | public void setName(String name) {
22 | this.name = name;
23 | }
24 |
25 | public String getType() {
26 | return type;
27 | }
28 |
29 | public void setType(String type) {
30 | this.type = type;
31 | }
32 |
33 | public String getKey() {
34 | return key;
35 | }
36 |
37 | public void setKey(String key) {
38 | this.key = key;
39 | }
40 |
41 | public String getIsNullable() {
42 | return isNullable;
43 | }
44 |
45 | public void setIsNullable(String isNullable) {
46 | this.isNullable = isNullable;
47 | }
48 |
49 | public String getComment() {
50 | return comment;
51 | }
52 |
53 | public void setComment(String comment) {
54 | this.comment = comment;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/resources/database-mongo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 | ${dbName}数据库设计文档
14 | 表汇总
15 |
16 |
17 |
18 |
19 | | 名称 |
20 | 备注 |
21 |
22 |
23 |
24 |
25 | <#list tables as item>
26 |
27 | | ${item.table} |
28 | ${item.comment?default('')} |
29 |
30 |
31 | #list>
32 |
33 |
34 | 表明细
35 | <#list tables as item>
36 |
37 | ${item.table}
38 |
39 |
40 |
41 | | 列名 |
42 | 类型 |
43 | 注释 |
44 |
45 |
46 |
47 | <#list item.columns as column>
48 |
49 | | ${column.name} |
50 | ${column.type} |
51 | ${column.comment?default('')} |
52 |
53 | #list>
54 |
55 |
56 | #list>
57 |
58 |
59 |
--------------------------------------------------------------------------------
/src/main/resources/database.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 | ${dbName}数据库设计文档
14 | 表汇总
15 |
16 |
17 |
18 |
19 | | 名称 |
20 | 备注 |
21 | 记录数 |
22 | 数据量 |
23 |
24 |
25 |
26 | <#list tables as item>
27 |
28 | | ${item.table} |
29 | ${item.comment?default('')} |
30 | ${item.rows?default('')} |
31 | ${item.dataLengthHuman?default('')} |
32 |
33 | #list>
34 |
35 |
36 | 表明细
37 | <#list tables as item>
38 |
39 | ${item.comment?default('')}(${item.table})
40 |
41 |
42 |
43 | | 列名 |
44 | 类型 |
45 | KEY |
46 | 可否为空 |
47 | 注释 |
48 |
49 |
50 |
51 | <#list item.columns as column>
52 |
53 | | ${column.name} |
54 | ${column.type} |
55 | ${column.key?default('')} |
56 | ${column.isNullable?default('')} |
57 | ${column.comment?default('')} |
58 |
59 | #list>
60 |
61 |
62 | #list>
63 |
64 |
65 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # database-doc-generator
2 | 数据库文档生成器
3 |
4 | - 该工具根据给定的链接生成数据库文档,如果你嫌powerdesigner太重,那么可以试试该工具。
5 | - 支持的数据库类型:
6 | - MySQL
7 | - Oracle
8 | - SQLServer
9 | - MongoDB
10 | - PostgreSQL
11 |
12 | - 你可以下载[release](https://github.com/enilu/database-doc-generator/releases/tag/1.3.0)包来或者下载源代码来使用。
13 | - 如果使用源代码,需要先克隆该项目后运行mvn package打包,然后运行发布报中bin/start.bat
14 | - 运行程序后按照下面提示输入对应数据库参数:
15 |
16 | ```bash
17 | choose database:
18 | 1:mysql
19 | 2:oracle
20 | 3:PostgreSQL
21 | Select the appropriate numbers choose database type
22 | (Enter 'c' to cancel): 3
23 | input database name:
24 | gunslite
25 | input host:
26 | localhost
27 | input port:
28 | 5432
29 | input username:
30 | enilu
31 | input password:
32 | 123456
33 |
34 | ```
35 | - 输入完成后回车,即可生成数据库文档目录${dbname}-doc,目录中文档有三种形式:单文件html,word,markdown
36 |
37 | 其中markdown可以用来生成html用于在线查看数据库文档:
38 |
39 | 
40 |
41 | - 确保安装了gitbook后,进入上述文件目录的命令行窗口运行:gitbook serve
42 | ```bash
43 | E:\\database-doc-generator-20181006100721\guns-lite-doc>gitbook serve
44 | openssl config failed: error:02001003:system library:fopen:No such process
45 | Live reload server started on port: 35729
46 | Press CTRL+C to quit ...
47 |
48 | info: 7 plugins are installed
49 | info: loading plugin "livereload"... OK
50 | info: loading plugin "highlight"... OK
51 | info: loading plugin "search"... OK
52 | info: loading plugin "lunr"... OK
53 | info: loading plugin "sharing"... OK
54 | info: loading plugin "fontsettings"... OK
55 | info: loading plugin "theme-default"... OK
56 | info: found 15 pages
57 | info: found 0 asset files
58 | info: >> generation finished with success in 1.6s !
59 |
60 | Starting server ...
61 | Serving book on http://localhost:4000
62 | ```
63 | - 访问 http://localhost:4000,即可在线查看数据库文档
64 |
65 | 
66 |
67 | 
--------------------------------------------------------------------------------
/src/main/java/cn/enilu/tool/database/doc/generator/bean/TableVo.java:
--------------------------------------------------------------------------------
1 | package cn.enilu.tool.database.doc.generator.bean;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * TableVo
7 | *
8 | * @author zt
9 | * @version 2018/10/6 0006
10 | */
11 | public class TableVo {
12 | private String table;
13 | private String comment;
14 | /**
15 | * 表的记录数
16 | */
17 | private Long rows;
18 | /**
19 | * 表数据占用空间大小,单位(字节数)
20 | */
21 | private Long dataLength=0L;
22 | /**
23 | * 表数据占用空间大小,易于阅读的格式XX GB XX Mb XX KB
24 | */
25 | public String dataLengthHuman="0";
26 | private List columns;
27 |
28 | public String getTable() {
29 | return table;
30 | }
31 |
32 | public void setTable(String table) {
33 | this.table = table;
34 | }
35 |
36 | public String getComment() {
37 | return comment;
38 | }
39 |
40 | public void setComment(String comment) {
41 | this.comment = comment;
42 | }
43 |
44 | public List getColumns() {
45 | return columns;
46 | }
47 |
48 | public void setColumns(List columns) {
49 | this.columns = columns;
50 | }
51 |
52 | public Long getRows() {
53 | return rows;
54 | }
55 |
56 | public void setRows(Long rows) {
57 | this.rows = rows;
58 | }
59 |
60 | public Long getDataLength() {
61 | return dataLength;
62 | }
63 |
64 | public void setDataLength(Long dataLength) {
65 | this.dataLength = dataLength;
66 | }
67 |
68 | public String getDataLengthHuman() {
69 | long temp = 0;
70 | String humanLength = "0KB";
71 | if(dataLength>1024){
72 | temp = dataLength/1024;
73 | humanLength = temp+"KB";
74 | }
75 | if(temp>1024){
76 | temp = temp/1024;
77 | humanLength = temp+"MB";
78 | }
79 | if(temp>1024){
80 | temp = temp/1024;
81 | humanLength = temp+"GB";
82 | }
83 | setDataLengthHuman(humanLength);
84 | return dataLengthHuman;
85 | }
86 |
87 | public void setDataLengthHuman(String dataLengthHuman) {
88 | this.dataLengthHuman = dataLengthHuman;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/main/java/cn/enilu/tool/database/doc/generator/bean/DdgDataSource.java:
--------------------------------------------------------------------------------
1 | package cn.enilu.tool.database.doc.generator.bean;
2 |
3 | import org.nutz.dao.impl.SimpleDataSource;
4 |
5 | /**
6 | * 自定义数据源
7 | *
8 | * @Author enilu
9 | * @Date 2021/4/28 10:14
10 | * @Version 1.0
11 | */
12 |
13 | public class DdgDataSource {
14 | private int dbType;
15 | private String ip;
16 | private String port;
17 | private String user;
18 | private String pass;
19 | private String dbName;
20 |
21 | public SimpleDataSource getDs(){
22 | SimpleDataSource dataSource = new SimpleDataSource();
23 |
24 | if (Constants.DB_MYSQL == dbType) {
25 | dataSource.setJdbcUrl("jdbc:mysql://" + ip + ":" + port + "/" + dbName);
26 | } else if (Constants.DB_ORACLE == dbType) {
27 | dataSource.setJdbcUrl("jdbc:oracle:thin:@" + ip + ":" + port + ":" + dbName);
28 | } else if (Constants.DB_POSTGRESQL == dbType) {
29 | dataSource.setJdbcUrl("jdbc:postgresql://" + ip + ":" + port + "/" + dbName);
30 | } else if (Constants.DB_SQLSERVER == dbType) {
31 | dataSource.setJdbcUrl("jdbc:sqlserver://" + ip + ":" + port + ";database=" + dbName);
32 | }
33 | dataSource.setUsername(user);
34 | dataSource.setPassword(pass);
35 | return dataSource;
36 | }
37 |
38 | public int getDbType() {
39 | return dbType;
40 | }
41 |
42 | public void setDbType(int dbType) {
43 | this.dbType = dbType;
44 | }
45 |
46 | public String getIp() {
47 | return ip;
48 | }
49 |
50 | public void setIp(String ip) {
51 | this.ip = ip;
52 | }
53 |
54 | public String getPort() {
55 | return port;
56 | }
57 |
58 | public void setPort(String port) {
59 | this.port = port;
60 | }
61 |
62 | public String getUser() {
63 | return user;
64 | }
65 |
66 | public void setUser(String user) {
67 | this.user = user;
68 | }
69 |
70 | public String getPass() {
71 | return pass;
72 | }
73 |
74 | public void setPass(String pass) {
75 | this.pass = pass;
76 | }
77 |
78 | public String getDbName() {
79 | return dbName;
80 | }
81 |
82 | public void setDbName(String dbName) {
83 | this.dbName = dbName;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/cn/enilu/tool/database/doc/generator/doc/Html2DocConverter.java:
--------------------------------------------------------------------------------
1 | package cn.enilu.tool.database.doc.generator.doc;
2 |
3 | import org.apache.poi.poifs.filesystem.DirectoryEntry;
4 | import org.apache.poi.poifs.filesystem.POIFSFileSystem;
5 |
6 | import java.io.*;
7 |
8 | /**
9 | * Html2DocConverter
10 | *
11 | * @author zt
12 | * @version 2019/1/12 0012
13 | */
14 | public class Html2DocConverter {
15 |
16 | private String inputPath; // 输入文件路径,以.html结尾
17 | private String outputPath; // 输出文件路径,以.doc结尾
18 |
19 | public Html2DocConverter(String inputPath, String outputPath) {
20 | super();
21 | this.inputPath = inputPath;
22 | this.outputPath = outputPath;
23 | }
24 |
25 | /**
26 | * 读取html文件到word
27 | *
28 | * @param filepath
29 | * html文件的路径
30 | * @return
31 | * @throws Exception
32 | */
33 | public boolean writeWordFile() throws Exception {
34 |
35 | InputStream is = null;
36 | FileOutputStream fos = null;
37 |
38 | // 1 找不到源文件, 则返回false
39 | File inputFile = new File(this.inputPath);
40 | if (!inputFile.exists()) {
41 | return false;
42 | }
43 |
44 | File outputFile = new File(this.outputPath);
45 | // 2 如果目标路径不存在 则新建该路径
46 | if (!outputFile.getParentFile().exists()) {
47 | outputFile.getParentFile().mkdirs();
48 | }
49 |
50 | try {
51 |
52 | // 3 将html文件内容写入doc文件
53 | is = new FileInputStream(inputFile);
54 | POIFSFileSystem poifs = new POIFSFileSystem();
55 | DirectoryEntry directory = poifs.getRoot();
56 | directory.createDocument(
57 | "WordDocument", is);
58 |
59 | fos = new FileOutputStream(this.outputPath);
60 | poifs.writeFilesystem(fos);
61 |
62 | System.out.println("转换word文件完成!");
63 |
64 | return true;
65 | } catch (IOException e) {
66 | e.printStackTrace();
67 | } finally {
68 | if (fos != null) {
69 | fos.close();
70 | }
71 | if (is != null) {
72 | is.close();
73 | }
74 | }
75 |
76 | return false;
77 | }
78 | public static void main(String[] args) throws Exception {
79 |
80 | new Html2DocConverter("G:/123.html" , "G:/temp5.doc").writeWordFile();
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/cn/enilu/tool/database/doc/generator/database/Oracle.java:
--------------------------------------------------------------------------------
1 | package cn.enilu.tool.database.doc.generator.database;
2 |
3 | import cn.enilu.tool.database.doc.generator.bean.ColumnVo;
4 | import cn.enilu.tool.database.doc.generator.bean.DdgDataSource;
5 | import cn.enilu.tool.database.doc.generator.bean.TableVo;
6 | import org.nutz.dao.entity.Record;
7 | import org.nutz.dao.impl.SimpleDataSource;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | /**
13 | * Oracle
14 | *
15 | * @author zt
16 | * @version 2019/1/6 0006
17 | */
18 | public class Oracle extends Generator{
19 | private String sqlTables = "select * from user_tab_comments";
20 | private String sqlColumns = "select column_name,data_type,data_length,nullable from user_tab_columns where " +
21 | "Table_Name='@tablename'";
22 | private String sqlColumnComments = "select column_name,comments from user_col_comments where TABLE_NAME='@tablename'";
23 | public Oracle(String dbName, DdgDataSource dataSource) {
24 | super(dbName, dataSource);
25 | }
26 |
27 | @Override
28 | public List getTableData() {
29 | List list = getList(sqlTables);
30 | List tables = new ArrayList<>();
31 | for(int i=0;i columns = getList(sql);
47 | List columnComments = getList(sql2);
48 | List columnVoList = new ArrayList<>();
49 | for(int i=0;i 0 and a.attrelid = c.oid and a.atttypid = t.oid" +
25 | " ORDER BY a.attnum";
26 |
27 | public PostgreSQL(String dbName, DdgDataSource dataSource) {
28 | super(dbName, dataSource);
29 | }
30 |
31 | @Override
32 | public List getTableData() {
33 | List list = getList(sqlTables);
34 | List tables = new ArrayList<>();
35 | for(int i=0;i columns = getList(sql);
51 |
52 | List columnVoList = new ArrayList<>();
53 | for(int i=0;i list) {
40 | Map map = new HashMap();
41 | map.put("dbName", dbName);
42 | map.put("tables", list);
43 | try {
44 | Template template = configuration.getTemplate(Constants.DB_MONGO == dbType?"database-mongo.html":"database.html");
45 | String name = dbName + "-doc" + File.separator + dbName + ".html";
46 | File f = new File(name);
47 | Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
48 | template.process(map, w);
49 | w.close();
50 | new Html2DocConverter(dbName + "-doc" + File.separator + dbName + ".html", dbName + "-doc" + File
51 | .separator + dbName + ".doc")
52 | .writeWordFile();
53 | } catch (Exception ex) {
54 | ex.printStackTrace();
55 |
56 | }
57 |
58 | }
59 |
60 |
61 | public static void main(String[] args) throws Exception {
62 | Map map = new HashMap();
63 | List list = new ArrayList<>();
64 | for (int i = 0; i < 5; i++) {
65 | TableVo tableVo = new TableVo();
66 | tableVo.setTable("表" + i);
67 | tableVo.setComment("注释" + i);
68 | List columns = new ArrayList<>();
69 | for (int j = 0; j < 5; j++) {
70 | ColumnVo columnVo = new ColumnVo();
71 | columnVo.setName("name" + j);
72 | columnVo.setComment("注释" + j);
73 | columnVo.setKey("PRI");
74 | columnVo.setIsNullable("是");
75 | columnVo.setType("varchar(2");
76 | columns.add(columnVo);
77 |
78 | }
79 | tableVo.setColumns(columns);
80 | list.add(tableVo);
81 | }
82 |
83 | createDoc(Constants.DB_MYSQL,"test", list);
84 |
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/java/cn/enilu/tool/database/doc/generator/database/MySQL.java:
--------------------------------------------------------------------------------
1 | package cn.enilu.tool.database.doc.generator.database;
2 | import cn.enilu.tool.database.doc.generator.bean.ColumnVo;
3 | import cn.enilu.tool.database.doc.generator.bean.DdgDataSource;
4 | import cn.enilu.tool.database.doc.generator.bean.TableVo;
5 | import org.nutz.dao.entity.Record;
6 | import org.nutz.dao.impl.SimpleDataSource;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | /**
12 | * DatabaseDocService
13 | *
14 | * @author zt
15 | * @version 2018/10/6 0006
16 | */
17 | public class MySQL extends Generator {
18 | String sqlTables = "select table_name,table_comment,table_rows,data_length from information_schema.tables where table_schema = '@dbname'" +
19 | " order by table_name asc";
20 | String sqlColumns = "select column_name,column_type,column_key,is_nullable,column_comment from information_schema" +
21 | ".columns where table_schema = '@dbname' and table_name " +
22 | "='@tablename'";
23 |
24 | public MySQL(String dbName, DdgDataSource dataSource){
25 | super(dbName,dataSource);
26 | }
27 | @Override
28 | public List getTableData(){
29 | String sql = sqlTables.replace("@dbname",dbName);
30 | List list = getList(sql);
31 | List tables = new ArrayList<>();
32 | for(int i=0;i list =getList(sql);
55 | List columns = new ArrayList<>();
56 | for(int i=0;i getTableData() {
59 | List list = getList(sqlTables);
60 | List tables = new ArrayList<>();
61 | for (int i = 0; i < list.size(); i++) {
62 | Record record = list.get(i);
63 | String table = record.getString("name");
64 | String comment = record.getString("comment");
65 | TableVo tableVo = getTableInfo(table, comment);
66 | tables.add(tableVo);
67 | }
68 | return tables;
69 | }
70 |
71 | public TableVo getTableInfo(String table,String tableComment){
72 | TableVo tableVo = new TableVo();
73 | tableVo.setTable(table);
74 | tableVo.setComment(tableComment);
75 | String sql = sqlColumns.replace("@tablename",table);
76 | List list =getList(sql);
77 | List columns = new ArrayList<>();
78 | for(int i=0;i getTableData() {
44 | List tables = new ArrayList<>();
45 | Set collectionNames = zMoDB.cNames();
46 | Iterator iter = collectionNames.iterator();
47 | while (iter.hasNext()) {
48 | String collectionname = iter.next();
49 | ZMoCo zMoCo = zMoDB.c(collectionname);
50 | ZMoDoc doc = zMoCo.findOne();
51 | TableVo tableVo = getTableInfo(doc, collectionname);
52 | if (tableVo != null) {
53 | tables.add(tableVo);
54 | }
55 | }
56 |
57 |
58 | return tables;
59 | }
60 |
61 | private TableVo getTableInfo(ZMoDoc doc, String tableName) {
62 | TableVo tableVo = new TableVo();
63 | tableVo.setTable(tableName);
64 | if (doc == null) {
65 | return null;
66 | }
67 | Set keys = doc.keySet();
68 | Iterator iter = keys.iterator();
69 | List columns = new ArrayList<>();
70 | while (iter.hasNext()) {
71 | ColumnVo column = new ColumnVo();
72 | String key = iter.next();
73 | column.setName(key);
74 | Object object = doc.get(key);
75 | getColumnInfo(null, key, object, columns);
76 |
77 | }
78 | tableVo.setColumns(columns);
79 | return tableVo;
80 | }
81 |
82 | private void getColumnInfo(String parent, String key, Object object, List columns) {
83 | if (object == null) {
84 | return;
85 | }
86 | if("__v".equalsIgnoreCase(key) || "_class".equalsIgnoreCase(key)){
87 | return ;
88 | }
89 |
90 | String currentKey = Strings.isNotBlank(parent) ? (parent + "." + key) : key;
91 |
92 | ColumnVo column = new ColumnVo();
93 | column.setName(currentKey);
94 | columns.add(column);
95 | if (object instanceof String) {
96 |
97 | column.setType("string");
98 | } else if (object instanceof Integer) {
99 |
100 | column.setType("integer");
101 | } else if (object instanceof BasicDBList) {
102 | column.setType("list");
103 | currentKey = key+"[]";
104 | column.setName(currentKey);
105 | BasicDBList list = (BasicDBList) object;
106 | if (list.size() > 0) {
107 |
108 | Object object2 = list.get(0);
109 | getColumnInfo(currentKey, currentKey, object2, columns);
110 | } else {
111 | columns.remove(column);
112 | }
113 |
114 | } else if (object instanceof BasicDBObject) {
115 | column.setType("object");
116 | if(parent!=null&&parent.contains("[]")){
117 | columns.remove(column);
118 | }
119 |
120 | BasicDBObject dbObject = (BasicDBObject) object;
121 | Iterator iter = dbObject.keySet().iterator();
122 | while (iter.hasNext()) {
123 | String key2 = iter.next();
124 | if(parent!=null&&parent.contains("[]")){
125 | getColumnInfo(parent, key2, dbObject.get(key2), columns);
126 | }else {
127 | getColumnInfo(currentKey, key2, dbObject.get(key2), columns);
128 | }
129 | }
130 | } else if (object instanceof Boolean) {
131 | column.setType("boolean");
132 | } else if (object instanceof Double) {
133 | column.setType("double");
134 | } else if (object instanceof ObjectId) {
135 | columns.remove(column);
136 | } else if (object instanceof Date) {
137 | column.setType("date");
138 | } else if (object instanceof Long) {
139 | column.setType("long");
140 | } else {
141 | column.setType(object.getClass().getName());
142 | }
143 |
144 |
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/main/java/cn/enilu/tool/database/doc/generator/database/Generator.java:
--------------------------------------------------------------------------------
1 | package cn.enilu.tool.database.doc.generator.database;
2 |
3 | import cn.enilu.tool.database.doc.generator.bean.ColumnVo;
4 | import cn.enilu.tool.database.doc.generator.bean.Constants;
5 | import cn.enilu.tool.database.doc.generator.bean.DdgDataSource;
6 | import cn.enilu.tool.database.doc.generator.bean.TableVo;
7 | import cn.enilu.tool.database.doc.generator.doc.WordGenerator;
8 | import org.nutz.dao.Dao;
9 | import org.nutz.dao.Sqls;
10 | import org.nutz.dao.entity.Record;
11 | import org.nutz.dao.impl.NutDao;
12 | import org.nutz.dao.impl.SimpleDataSource;
13 | import org.nutz.dao.sql.Sql;
14 | import org.nutz.lang.Files;
15 | import org.nutz.lang.Strings;
16 |
17 | import java.io.File;
18 | import java.util.List;
19 | import java.util.Scanner;
20 |
21 | /**
22 | * Generator
23 | *
24 | * @author zt
25 | * @version 2019/1/6 0006
26 | */
27 | public abstract class Generator {
28 | private SimpleDataSource dataSource;
29 | private DdgDataSource ddgDataSource;
30 | protected Dao dao = null;
31 | protected String dbName;
32 | protected String docPath;
33 |
34 | public Generator(String dbName, DdgDataSource dataSource) {
35 | this.ddgDataSource = dataSource;
36 | if(Constants.DB_MONGO != dataSource.getDbType()){
37 |
38 | this.dataSource = dataSource.getDs();
39 | dao = new NutDao(this.dataSource);
40 | }
41 | this.dbName = dbName;
42 | this.docPath = dbName + "-doc";
43 | }
44 |
45 | /**
46 | * 获取表结构数据
47 | *
48 | * @return
49 | */
50 | public abstract List getTableData();
51 |
52 | public void generateDoc() {
53 | File docDir = new File(docPath);
54 | if (docDir.exists()) {
55 |
56 | String str = "\n【温馨提示】 - 文件夹" + docPath + "已存在。 是否删除?(y 默认删除)\n";
57 | //throw new RuntimeException(str);
58 | System.out.print(str);
59 |
60 | Scanner sc = new Scanner(System.in);
61 | String dbType = sc.nextLine();
62 | if ("y".equals(dbType) || "".equals(dbType)) {
63 | docDir.delete();
64 | }
65 | else
66 | {
67 | return;
68 | }
69 | } else {
70 | docDir.mkdirs();
71 | }
72 | List list = getTableData();
73 | save2File(list);
74 | //保存word
75 | WordGenerator.createDoc(ddgDataSource.getDbType(),dbName,list);
76 |
77 | }
78 |
79 | public void save2File(List tables) {
80 | saveSummary(tables);
81 | saveReadme(tables);
82 | for (TableVo tableVo : tables) {
83 | saveTableFile(tableVo);
84 | }
85 | }
86 |
87 | private void saveSummary(List tables) {
88 | StringBuilder builder = new StringBuilder("# Summary").append("\r\n").append("* [Introduction](README.md)")
89 | .append("\r\n");
90 | for (TableVo tableVo : tables) {
91 | String name = Strings.isEmpty(tableVo.getComment()) ? tableVo.getTable() : tableVo.getComment();
92 | builder.append("* [" + name + "](" + tableVo.getTable() + ".md)").append("\r\n");
93 | }
94 | try {
95 | Files.write(new File(docPath + File
96 | .separator + "SUMMARY.md"), builder.toString());
97 | } catch (Exception e) {
98 | e.printStackTrace();
99 | }
100 | }
101 |
102 | private void saveReadme(List tables) {
103 | StringBuilder builder = new StringBuilder("# " + dbName + "数据库文档").append("\r\n");
104 | for (TableVo tableVo : tables) {
105 | builder.append("- [" + (Strings.isEmpty(tableVo.getComment()) ? tableVo.getTable() : tableVo.getComment())
106 | + "]" +
107 | "(" + tableVo
108 | .getTable() + ".md)")
109 | .append
110 | ("\r\n");
111 | }
112 | try {
113 | Files.write(new File(docPath + File
114 | .separator + "README.md"), builder.toString());
115 | } catch (Exception e) {
116 | e.printStackTrace();
117 | }
118 | }
119 |
120 | private void saveTableFile(TableVo table) {
121 |
122 | StringBuilder builder = new StringBuilder("# " + (Strings.isBlank(table.getComment()) ? table.getTable() : table
123 | .getComment()) + "(" + table.getTable() + ")").append("\r\n");
124 | builder.append("| 列名 | 类型 | KEY | 可否为空 | 注释 |").append("\r\n");
125 | builder.append("| ---- | ---- | ---- | ---- | ---- |").append("\r\n");
126 | List columnVos = table.getColumns();
127 | for (int i = 0; i < columnVos.size(); i++) {
128 | ColumnVo column = columnVos.get(i);
129 | builder.append("|").append(column.getName()).append("|").append(column.getType()).append("|").append
130 | (Strings.sNull(column.getKey())).append("|").append(column.getIsNullable()).append("|").append
131 | (column.getComment()).append("|\r\n");
132 | }
133 | try {
134 | Files.write(new File(docPath + File
135 | .separator + table.getTable() + ".md"), builder.toString());
136 | } catch (Exception e) {
137 | e.printStackTrace();
138 | }
139 | }
140 |
141 | public List getList(String sqlStr) {
142 | Sql sql = Sqls.create(sqlStr);
143 | sql.setCallback(Sqls.callback.records());
144 | dao.execute(sql);
145 | List list = sql.getList(Record.class);
146 | return list;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/src/main/java/cn/enilu/tool/database/doc/generator/Main.java:
--------------------------------------------------------------------------------
1 | package cn.enilu.tool.database.doc.generator;
2 |
3 | import cn.enilu.tool.database.doc.generator.bean.Constants;
4 | import cn.enilu.tool.database.doc.generator.bean.DdgDataSource;
5 | import cn.enilu.tool.database.doc.generator.database.*;
6 | import org.nutz.dao.impl.SimpleDataSource;
7 |
8 | import java.util.Scanner;
9 |
10 | /**
11 | * Main
12 | *
13 | * @author zt
14 | * @version 2018/10/6 0006
15 | */
16 | public class Main {
17 | public static void main(String[] args) {
18 | Scanner sc = new Scanner(System.in);
19 | System.out.print("choose database:\n1:MySQL\n2:Oracle\n3:PostgreSQL\n4:SQLServer\n5:MongoDB\n" +
20 | "Select the appropriate numbers choose database type\n" +
21 | "(Enter 'c' to cancel):\n ");
22 | int dbType = Integer.valueOf(sc.nextLine());
23 | if ("c".equals(dbType)) {
24 | System.exit(-1);
25 | }
26 | if (Integer.valueOf(dbType) < 1 || Integer.valueOf(dbType) > 5) {
27 | System.out.println("wrong number,will exit");
28 | System.exit(-1);
29 | }
30 | String serviceName = null;
31 | String dbName = null;
32 | if (Constants.DB_ORACLE == dbType) {
33 | System.out.println("input service name:");
34 | serviceName = sc.nextLine();
35 | } else {
36 | System.out.println("input database name:");
37 | dbName = sc.nextLine();
38 | }
39 | System.out.println("input host (default 127.0.0.1) :");
40 | String ip = sc.nextLine();
41 | if ("".equals(ip)) {
42 | ip = "127.0.0.1";
43 | }
44 |
45 | System.out.println("input port (default " + getDefaultPort(dbType) + ") :");
46 | String port = sc.nextLine();
47 | if ("".equals(port)) {
48 | port = getDefaultPort(dbType);
49 | }
50 |
51 | System.out.println("input username (default " + getDefaultUser(dbType) + ") :");
52 | String username = sc.nextLine();
53 | if ("".equals(username)) {
54 | username = getDefaultUser(dbType);
55 | }
56 |
57 | System.out.println("input password (default 123456) :");
58 | String passowrd = sc.nextLine();
59 | if ("".equals(passowrd)) {
60 | passowrd = "123456";
61 | }
62 |
63 | // SimpleDataSource dataSource = new SimpleDataSource();
64 | // if ("1".equals(dbType)) {
65 | // dataSource.setJdbcUrl("jdbc:mysql://" + ip + ":" + port + "/" + dbName);
66 | // } else if ("2".equals(dbType)) {
67 | // dataSource.setJdbcUrl("jdbc:oracle:thin:@" + ip + ":" + port + ":" + serviceName);
68 | // } else if ("3".equals(dbType)) {
69 | // dataSource.setJdbcUrl("jdbc:postgresql://" + ip + ":" + port + "/" + dbName);
70 | // } else if ("4".equals(dbType)) {
71 | // dataSource.setJdbcUrl("jdbc:sqlserver://" + ip + ":" + port + ";database=" + dbName);
72 | // }else if("5".equalsIgnoreCase(dbType)){
73 | //
74 | // }
75 | // dataSource.setUsername(username);
76 | // dataSource.setPassword(passowrd);
77 | DdgDataSource dataSource = new DdgDataSource();
78 | dataSource.setDbType(dbType);
79 | dataSource.setIp(ip);
80 | dataSource.setPort(port);
81 | dataSource.setDbName("2".equals(dbType) ? serviceName : dbName);
82 | dataSource.setUser(username);
83 | dataSource.setPass(passowrd);
84 | Generator generator = null;
85 | switch (dbType) {
86 | case Constants.DB_MYSQL:
87 | generator = new MySQL(dbName, dataSource);
88 | break;
89 | case Constants.DB_ORACLE:
90 | generator = new Oracle(username, dataSource);
91 | break;
92 | case Constants.DB_POSTGRESQL:
93 | generator = new PostgreSQL(dbName, dataSource);
94 | break;
95 | case Constants.DB_SQLSERVER:
96 | generator = new SqlServer(dbName, dataSource);
97 | case Constants.DB_MONGO:
98 | generator = new Mongo(dbName, dataSource);
99 | default:
100 | System.out.println("not support database");
101 | break;
102 | }
103 |
104 | generator.generateDoc();
105 | }
106 |
107 | private static String getDefaultPort(int dbType) {
108 | String defaultPort = "";
109 |
110 | switch (dbType) {
111 | case Constants.DB_MYSQL: {
112 | defaultPort = "3306";
113 | break;
114 | }
115 | case Constants.DB_ORACLE: {
116 | defaultPort = "1521";
117 | break;
118 | }
119 | case Constants.DB_POSTGRESQL: {
120 | defaultPort = "5432";
121 | break;
122 | }
123 | case Constants.DB_SQLSERVER: {
124 | defaultPort = "1433";
125 | break;
126 | }
127 | case Constants.DB_MONGO: {
128 | defaultPort = "27017";
129 | break;
130 | }
131 | default: {
132 | defaultPort = "-";
133 | break;
134 | }
135 | }
136 |
137 | return defaultPort;
138 | }
139 |
140 | private static String getDefaultUser(int dbType) {
141 | String defaultUser = "";
142 |
143 | switch (dbType) {
144 | case Constants.DB_MYSQL: {
145 | defaultUser = "root";
146 | break;
147 | }
148 | case Constants.DB_ORACLE: {
149 | defaultUser = "sytem";
150 | break;
151 | }
152 | case Constants.DB_POSTGRESQL: {
153 | defaultUser = "postgres";
154 | break;
155 | }
156 | case Constants.DB_SQLSERVER: {
157 | defaultUser = "sa";
158 | break;
159 | }
160 | default: {
161 | defaultUser = "";
162 | break;
163 | }
164 | }
165 |
166 | return defaultUser;
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | cn.enilu
8 | database-doc-generator
9 | 1.0
10 |
11 | UTF-8
12 | yyyyMMddHHmmss
13 | 1.8
14 | 1.8
15 | UTF-8
16 | true
17 |
18 |
19 |
20 | org.nutz
21 | nutz
22 | 1.r.66
23 |
24 |
25 | mysql
26 | mysql-connector-java
27 | 5.1.24
28 |
29 |
30 | org.postgresql
31 | postgresql
32 | 42.2.5
33 |
34 |
35 | com.oracle
36 | ojdbc14
37 | 10.2.0.4.0
38 |
39 |
40 | com.microsoft.sqlserver
41 | sqljdbc42
42 | 4.0
43 | system
44 | ${project.basedir}/sqljdbc42.jar
45 |
46 |
47 |
48 | org.nutz
49 | nutzmongo
50 | 1.r.60
51 |
52 |
53 | org.freemarker
54 | freemarker
55 | 2.3.28
56 |
57 |
58 | org.apache.poi
59 | poi
60 | 3.12
61 |
62 |
63 |
64 |
65 |
66 | org.apache.maven.plugins
67 | maven-compiler-plugin
68 | 3.0
69 |
70 | ${project.build.sourceEncoding}
71 | ${java_source_version}
72 | ${java_target_version}
73 | -Xlint:unchecked
74 |
75 |
76 |
77 |
78 | org.apache.maven.plugins
79 | maven-surefire-plugin
80 |
81 | ${skipTests}
82 |
83 |
84 |
85 | maven-war-plugin
86 | 2.3
87 |
88 | webapp
89 |
90 |
91 |
92 | org.apache.maven.plugins
93 | maven-resources-plugin
94 | 2.6
95 |
96 | ${project.build.sourceEncoding}
97 |
98 |
99 |
100 |
101 | org.codehaus.mojo
102 | truezip-maven-plugin
103 | 1.1
104 |
105 |
106 | remove-a-file-in-sub-archive
107 |
108 | remove
109 |
110 | package
111 |
112 |
113 | ${project.basedir}/lib
114 |
115 | *.jar
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | org.apache.maven.plugins
125 | maven-dependency-plugin
126 | 2.8
127 |
128 |
129 | copy-dependencies
130 | package
131 |
132 | copy-dependencies
133 |
134 |
135 | ${project.basedir}/lib
136 | false
137 | true
138 |
139 |
140 |
141 |
142 |
143 | maven-assembly-plugin
144 | 2.4
145 |
146 | false
147 | ${project.artifactId}-${build.timestamp}
148 |
149 | dist.xml
150 |
151 |
152 |
153 |
154 | make-assembly
155 | package
156 |
157 | assembly
158 |
159 |
160 |
161 |
162 |
163 | org.apache.maven.plugins
164 | maven-jar-plugin
165 | 2.6
166 |
167 |
168 |
169 | **/*.properties
170 |
171 |
172 |
173 |
174 |
175 |
176 |
--------------------------------------------------------------------------------