一般所有的项目都需要数据库设计文档,对于表不多的可以编辑word文档,自己写,但对于表很多,字段很多的数据库,这时候写设计文档就很麻烦,楼主就是遇到这个问题,项目70张表,一个个写到文档里是在麻烦,所以就像有没有可以通过程序生成。
具体思路
- 通过jdbc获取所有的表名
- 然后获取所有表的字段描述
- 通过FreeMarker模版文件来生成word
注:首先通过jdbc连接你要生成word文档的数据库,怎么连接网上都有,这个不在这里多介绍。
通过jdbc获取所有的表名
- 可以使用
show tables
这个方法获取到库下所有的表,但是有时候可能需要表的注释,那就用另外一条语句
select table_name,table_comment from information_schema.tables where table_schema = 'TABLE_ACHEMA' //TABLE_ACHEMA就是数据库名
这里就直接使用executeQuery()方法就行:
result = stmt.executeQuery("select table_name,table_comment from information_schema.tables where table_schema = 'pension_service'");
while (result.next()){
String name = result.getString(1);//表名
String comment = result.getString(2);//表注释
Table table=new Table();
table.setName(name);
table.setComment(comment);
tables.add(table);
}
获取到后可以放到自己写的一个实体类,作为FreeMarker模版文件的数据源
通过jdbc获取所有的表的字段
方法和上面一样
SQL:
select ORDINAL_POSITION,COLUMN_NAME,COLUMN_TYPE,EXTRA,COLUMN_COMMENT from information_schema.columns where table_schema ='TABLE_ACHEMA' and table_name = 'TABLE_NAME' "//TABLE_ACHEMA就是数据库名 TABLE_NAME表明表名
// ORDINAL_POSITION:列标识号。
// COLUMN_NAME:列名(字段名称)。
// COLUMN_TYPE:数据类型。
// EXTRA:额外信息(例如:auto_increment)
// COLUMN_NAME:列名(字段名称)。
// COLUMN_COMMENT:列注释
information_schema.columns 里存放了所有的字段的信息,这边可以自己自定义取哪些信息.
通过FreeMarker模版文件来生成word
首先要有自己的模版
Word 文档模板:普通的doc、docx都是二进制文件,操作起来比较麻烦,那么我们可以采用变通的方式,用word 的xml格式。
可以自己先在文档里做一个自己想要的表样式 例如:
然后另存为,选择xml格式
然后打开之后看一下,
不要被这么多代码恐吓到,仔细观察就可以找到word里的表格在xml怎么表示了,找到之后就可以生成我们所需要的模版文件,加上
<#list tables as table>//表循环
...
<#list table.columns as col>//表字段循环
...
</#list>
..
</#list>
在这边上传一个我这边用的模版供大家参考:
link
有了模版就可以直接生成文档了:代码:
public class WordHandler {
private Configuration configuration = null;
public WordHandler() {
configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
}
public void data2word( Map<String,Object> data) {
// 设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以servlet,classpath,数据库装载,
// 这里我们的模板是放在org.cnzjw.template包下面
configuration.setClassForTemplateLoading(this.getClass(),
"/");
Template t = null;
try {
// word.ftl为要装载的模板
t = configuration.getTemplate("table.ftl");
} catch (IOException e) {
e.printStackTrace();
}
// 输出文档路径及名称
File outFile = new File("/Users/gengqiang/Desktop/table.doc");
Writer out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outFile)));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
t.process(data, out);
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test() throws Exception {
WordHandler wh = new WordHandler();
List<Table> tables=TableHandler.getTables();//获取表结构数据
Map<String,Object> data=new HashMap<String,Object>();
data.put("tables",tables);
wh.data2word(data);
}
}
2个实体类:
package com.coderqiang.tabledoc.entity;
/**
* Created by gengqiang on 2017/6/27.
*/
public class Column {
private Integer index;
private String name;
private String dataType;
private String constraint;
private String comment;
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getConstraint() {
return constraint;
}
public void setConstraint(String constraint) {
this.constraint = constraint;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
@Override
public String toString() {
return "Column{" +
"index=" + index +
", name='" + name + '/'' +
", dataType='" + dataType + '/'' +
", constraint='" + constraint + '/'' +
", comment='" + comment + '/'' +
'}';
}
}
package com.coderqiang.tabledoc.entity;
import java.util.List;
/**
* Created by gengqiang on 2017/6/27.
*/
public class Table {
private String name;
private String comment;
private List<Column> columns;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public List<Column> getColumns() {
return columns;
}
public void setColumns(List<Column> columns) {
this.columns = columns;
}
@Override
public String toString() {
return "Table{" +
"name='" + name + '/'' +
", comment='" + comment + '/'' +
", columns=" + columns +
'}';
}
}
获取表结构数据:
package com.coderqiang.tabledoc.service;
import com.coderqiang.tabledoc.entity.Column;
import com.coderqiang.tabledoc.entity.Table;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
* Created by gengqiang on 2017/6/27.
*/
public class TableHandler {
/**
* @param args
*/
//驱动程序就是之前在classpath中配置的JDBC的驱动程序的JAR 包中
public static final String DBDRIVER = "com.mysql.jdbc.Driver";
//连接地址是由各个数据库生产商单独提供的,所以需要单独记住
public static final String DBURL = "jdbc:mysql://localhost:3306/pension_service";
//连接数据库的用户名
public static final String DBUSER = "****";
//连接数据库的密码
public static final String DBPASS = "****";
public static List<String> getTableNames() throws Exception
{
List<String> tableNames=new ArrayList<String>();
Connection con = null; //表示数据库的连接对象
Statement stmt = null; //表示数据库的更新操作
ResultSet result = null; //表示接收数据库的查询结果
Class.forName(DBDRIVER); //1、使用CLASS 类加载驱动程序
con = DriverManager.getConnection(DBURL,DBUSER,DBPASS); //2、连接数据库
stmt = con.createStatement(); //3、Statement 接口需要通过Connection 接口进行实例化操作
result = stmt.executeQuery("show tables"); //执行SQL 语句,查询数据库
while (result.next()){
String name = result.getString(1);
tableNames.add(name);
}
result.close();
con.close(); // 4、关闭数据库
return tableNames;
}
public static List<Table> getTables() throws Exception
{
List<Table> tables=new ArrayList<Table>();
Connection con = null; //表示数据库的连接对象
Statement stmt = null; //表示数据库的更新操作
ResultSet result = null; //表示接收数据库的查询结果
Class.forName(DBDRIVER); //1、使用CLASS 类加载驱动程序
con = DriverManager.getConnection(DBURL,DBUSER,DBPASS); //2、连接数据库
stmt = con.createStatement(); //3、Statement 接口需要通过Connection 接口进行实例化操作
result = stmt.executeQuery("select table_name,table_comment from information_schema.tables where table_schema = 'pension_service' /n"); //执行SQL 语句,查询数据库
while (result.next()){
String name = result.getString(1);
String comment = result.getString(2);
Table table=new Table();
table.setName(name);
table.setComment(comment);
tables.add(table);
}
for(Table table:tables)
{
List<Column>columns=new ArrayList<Column>();
//查询字段
result = stmt.executeQuery("select ORDINAL_POSITION,COLUMN_NAME,COLUMN_TYPE,EXTRA,COLUMN_COMMENT from information_schema.columns where table_schema ='pension_service' and table_name = '"+table.getName()+"' "); //执行SQL 语句,查询数据库
while (result.next()){
int index = result.getInt(1);
String name = result.getString(2);
String type = result.getString(3);
String constraint = result.getString(4);
String comment = result.getString(5);
Column column=new Column();
column.setIndex(index);
column.setName(name);
column.setDataType(type);
column.setConstraint(constraint);
column.setComment(comment);
columns.add(column);
}
table.setColumns(columns);
}
result.close();
con.close(); // 4、关闭数据库
return tables;
}
@Test
public void test()
{
try {
TableHandler.getTables();
} catch (Exception e) {
e.printStackTrace();
}
}
}
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/13829.html