自动生成数据库表设计(一)之获取JDBC获取元数据

2017-01-15  本文已影响366人  阿坤的博客

最近项目快了验收,那么接下来就是写一些比较烦人的文档,在写数据库设计文档时,到了详细设计这一块有点尴尬了,每张表,没个字段都要写上去,由于前期没有整理,所以这个工作量还是很大,我查看了我们的数据库发现有353张表,这样写,得花多久的时间啊。。。于是想通过程序来自动完成,这就是这篇文章的核心。

系列文章:
自动生成数据库表设计(一)之获取JDBC获取元数据
自动生成数据库表设计(二)之Freemarker的基本使用
自动生成数据库表设计(三)之制作word模版

本篇主要内容:
1、配置Maven工程
2、数据库元数据的获取

配置Maven工程

1、新建Maven工程
1.创建工程我这里创建的moudle类似于Eclipse的工程

新建一个db-generator的Moudle

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下

拷贝jar包

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简单的使用。

文档下载

上一篇下一篇

猜你喜欢

热点阅读