自动生成数据库表设计(一)之获取JDBC获取元数据
最近项目快了验收,那么接下来就是写一些比较烦人的文档,在写数据库设计文档时,到了详细设计这一块有点尴尬了,每张表,没个字段都要写上去,由于前期没有整理,所以这个工作量还是很大,我查看了我们的数据库发现有353张表,这样写,得花多久的时间啊。。。于是想通过程序来自动完成,这就是这篇文章的核心。
系列文章:
自动生成数据库表设计(一)之获取JDBC获取元数据
自动生成数据库表设计(二)之Freemarker的基本使用
自动生成数据库表设计(三)之制作word模版
本篇主要内容:
1、配置Maven工程
2、数据库元数据的获取
配置Maven工程
1、新建Maven工程
1.创建工程我这里创建的moudle类似于Eclipse的工程
2.指定Moudle路径
指定Moudle路径3.点击OK,编辑pom.xml (无所谓)
点击ok即可4.在main下新建lib文件夹,我们要拷贝Oracle的jdbc的jar包,我没找到maven依赖
创建完成的结构目录2、配置工程
1.创建好工程后,开始配置工程,由于我们的数据库是Oracle11g,这里我们先找到Oracle的JDBC的jar包,找到 安装目录下的product\11.2.0\dbhome_1\jdbc\lib 的odbc6.jar拷贝到工程的lib下
2.将jar包添加到依赖
选中工程-右键-open moudle settings
将jar包添加到依赖第4步选中我们odbc6所在的目录,也就是刚才新建的lib包
至此我们的工程配置完成。
数据库元数据的获取
1、预览模版样式确定需求(前提是你的数据库已经存在这些信息)
模版示例获取的内容有:
表:表名、表注释
列:列名、列注释、字段类型、默认值
那么我们就要获取数据库的这些东西。
根据表名获取列信息的SQL
SELECT
utc.table_name,utc.column_name,utc.data_type,utc.data_length,utc.data_default,ucc.comments,p.PRIMARY_KEY
FROM
user_tab_columns utc
LEFT JOIN --查询注释
user_col_comments ucc
ON
utc.table_name = ucc.table_name
AND
utc.column_name = ucc.column_name
LEFT JOIN --查询主键
(
SELECT
col.table_name table_name,
col.column_name column_name,
CASE con.constraint_type WHEN 'P' THEN 'true' ELSE 'false' END "PRIMARY_KEY"
FROM
user_constraints con,
user_cons_columns col
WHERE
con.constraint_name = col.constraint_name
AND
con.constraint_type = 'P'
) p
ON
utc.column_name = p.column_name
AND
p.table_name = utc.table_name
WHERE
utc.table_name = 'YJ_HL';
结果如下:
sql查询结果获取数据库表信息的SQL
SELECT * FROM user_tab_comments WHERE table_type='TABLE'
这里就不显示了,设计公司业务了
ok现在我们基本信息用sql已经完成,那么用jdbc执行这些sql基本就完成获取数据库元数据信息了。
3、编写JDBC获取元数据信息
getTableList如下
// 获取数据库中所有表的表名,并添加到列表结构中。
public static List getTableList(Connection conn) throws SQLException {
List<Map> tableList = new ArrayList<Map>();
String sql =
"SELECT * FROM user_tab_comments WHERE table_type='TABLE'";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Map map = new HashMap<>();
String TABLE_NAME = rs.getString("TABLE_NAME");
String COMMENTS = rs.getString("COMMENTS");
map.put("TABLE_NAME", TABLE_NAME);
map.put("COMMENTS", COMMENTS == null ? "" : COMMENTS);
//获取列
List<Map> columnList = getColumnList(conn, TABLE_NAME);
map.put("COLUMNS", columnList);
//这里是过滤特殊的表,比如只生成SYS开头的表
if (TABLE_NAME.startsWith("SYS"))
tableList.add(map);
System.out.println("TABLE_NAME ==>" + TABLE_NAME + " COMMENTS==>" + COMMENTS);
}
rs.close();
ps.close();
return tableList;
}
getColumnList如下
// 获取数据表中所有列的列名,并添加到列表结构中。
public static List getColumnList(Connection conn, String tableName)
throws SQLException {
List<Map> columnList = new ArrayList<Map>();
String sql =
"SELECT utc.table_name,utc.column_name,utc.data_type,utc.data_length,utc.data_default,utc.nullable,ucc.comments,p.PRIMARY_KEY " +
"FROM user_tab_columns utc " +
"LEFT JOIN user_col_comments ucc " + //--查询注释
"ON utc.table_name = ucc.table_name " +
"AND utc.column_name = ucc.column_name " +
"LEFT JOIN " + //--查询主键
"( SELECT col.table_name table_name, col.column_name column_name, CASE con.constraint_type WHEN 'P' THEN 'true' ELSE 'false' END PRIMARY_KEY " +
"FROM user_constraints con,user_cons_columns col " +
"WHERE con.constraint_name = col.constraint_name " +
"AND con.constraint_type = 'P') p " +
"ON utc.column_name = p.column_name " +
"AND p.table_name = utc.table_name " +
"WHERE utc.table_name = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, tableName);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Map map = new HashMap<>();
String COLUMN_NAME = rs.getString("COLUMN_NAME");
String DATA_TYPE = rs.getString("DATA_TYPE");//VARCHAR2
String DATA_LENGTH = rs.getString("DATA_LENGTH");//200
String DATA_DEFAULT = rs.getString("DATA_DEFAULT");
String NULLABLE = rs.getString("NULLABLE");
String COMMENTS = rs.getString("COMMENTS");
String PRIMARY_KEY = rs.getString("PRIMARY_KEY");
map.put("COLUMN_NAME", COLUMN_NAME);
map.put("DATA_TYPE", DATA_TYPE);
map.put("DATA_LENGTH", DATA_LENGTH);
map.put("DATA_DEFAULT", DATA_DEFAULT == null ? "" : DATA_DEFAULT);
map.put("NULLABLE", "N".equals(NULLABLE) ? false : true);
map.put("COMMENTS", COMMENTS == null ? "" : COMMENTS);
map.put("PRIMARY_KEY", "true".equals(PRIMARY_KEY) ? true : false);
columnList.add(map);
System.out.println("COLUMN_NAME ==>" + COLUMN_NAME + " DATA_TYPE==>" + DATA_TYPE + " DATA_LENGTH==>" + DATA_LENGTH + " NULLABLE==>" + NULLABLE + " COMMENTS==>" + COMMENTS + " PRIMARY_KEY==>" + PRIMARY_KEY);
}
rs.close();
ps.close();
return columnList;
}
4、测试
public static void main(String[] args) throws Exception {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "tiger");
List<Map> tableList = getTableList(conn);
conn.close();
FtUtil ftUtil = new FtUtil();
Map map = new HashMap<>();
map.put("table", tableList);
ftUtil.generateFile("/", "moban.xml", map, "D:/", "sys_moban.doc");
}
打印结果如下:
结果至此,我们基本完成需求中所需要的数据了
下一篇,我们讲Freemarker简单的使用。