根据数据库名生成数据库结构说明

2023-10-31

根据数据库名生成数据库结构说明

 

package com.cjm.common;

import java.io.File;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

public class CreateMetadata {
	private Connection cn = null;
	private List fieldTypes = null;
	private List executedTables = null;
	//private String[] types = {"TABLE", "VIEW"}; //只生成表和视图的数据字典
	private String[] types = {"TABLE"}; //只生成表和视图的数据字典
	
	private String driver;
	private String url;
	private String uid;
	private String pwd;
	private String catalog;
	private String schema;
	
	public CreateMetadata()throws Exception{
		initData();
		
		//initSqlServerDBParams();
		initOracleDBParams();
		
   		Class.forName(driver);
	   	this.cn = DriverManager.getConnection(url, uid, pwd);
	}
	
	private void initData(){
		//字符串类型
		fieldTypes = new ArrayList();
		fieldTypes.add("CHAR");
		fieldTypes.add("NCHAR");
		fieldTypes.add("VARCHAR");
		fieldTypes.add("NVARCHAR");
		fieldTypes.add("VARCHAR2");
		fieldTypes.add("NVARCHAR2");
		
		//排除以下表
		executedTables = new ArrayList();
		executedTables.add("dtproperties");
		executedTables.add("sysconstraints");
		executedTables.add("syssegments");
	}
	
	/**
	 * SqlServer数据库连接参数
	 */
	private void initSqlServerDBParams(){
		catalog = "test"; //SqlServer的数据库名
		schema = null;
		
		driver = "net.sourceforge.jtds.jdbc.Driver";
   		url = "jdbc:jtds:sqlserver://localhost:1433;DatabaseName=test";
   		uid = "test";
   		pwd = "test";
	}
	
	/**
	 * Oracle数据库连接参数
	 */
	private void initOracleDBParams(){
		catalog = null;
		schema = "GISAP"; //Oracle的用户名
		
		driver = "oracle.jdbc.driver.OracleDriver";
   		url = "jdbc:oracle:thin:@localhost:1521:ORCL";
   		uid = "gisap";
   		pwd = "1";
	}
	
	/**
	 * 取得一个表的所有主键字段
	 */
	private String getTablePrimaryKeys(String tableName){
		try{
			DatabaseMetaData dbmd = cn.getMetaData();
			ResultSet rs = dbmd.getPrimaryKeys(catalog, schema, tableName);
			StringBuffer sb = new StringBuffer(",");
			while(rs.next()){
				sb.append(rs.getString("COLUMN_NAME") + ",");
			}
			rs.close();
			
			return sb.toString();
		}catch(Exception ex){
			return "";
		}
	}
	/**
	 * 取得一个表的所有主键字段
	 */
	private String getSqlStr(String tableName){
		StringBuffer sql = new StringBuffer();
		sql.append(" SELECT A.COLUMN_NAME    字段名, ");
		sql.append("        A.DATA_TYPE      数据类型, ");
		sql.append("        A.DATA_LENGTH    长度, ");
		sql.append("        A.DATA_PRECISION 整数位, ");
		sql.append("        A.DATA_SCALE     小数位, ");
		sql.append("        A.NULLABLE       允许空值, ");
		sql.append("        A.DATA_DEFAULT   缺省值, ");
		sql.append("        B.COMMENTS       备注, ");
		sql.append("        C.INDEXCOUNT     索引次数 ");
		sql.append("   FROM USER_TAB_COLUMNS A, ");
		sql.append("        USER_COL_COMMENTS B, ");
		sql.append("        (SELECT COUNT(*) INDEXCOUNT, COLUMN_NAME ");
		sql.append("           FROM USER_IND_COLUMNS ");
		sql.append("          WHERE TABLE_NAME = '"+tableName+"' ");
		sql.append("          GROUP BY COLUMN_NAME) C ");
		sql.append("  WHERE A.TABLE_NAME = B.TABLE_NAME ");
		sql.append("    AND A.COLUMN_NAME = B.COLUMN_NAME ");
		sql.append("    AND A.COLUMN_NAME = C.COLUMN_NAME(+) ");
		sql.append("    AND A.TABLE_NAME = '"+tableName+"' ");
		return sql.toString();

	}
	
	/**
	 * 生成数据字典
	 */
	public void createTableMetadata(String fileName){
		try{
			if(fileName == null || fileName.length() == 0){
				throw new IllegalArgumentException("fileName is null");
			}

			System.out.println("fileName:"+fileName);			
			File file = new File(fileName);
			
			//delete old file
			if(file.exists() && file.isFile()) file.delete();
			
			//create sheet
			WritableWorkbook book = Workbook.createWorkbook(new FileOutputStream(file));
			WritableSheet sheet = book.createSheet("数据字典",0);
			
			DatabaseMetaData dbmd = cn.getMetaData();
			ResultSet rs = dbmd.getTables(catalog ,schema,"%", types);
			int rowIndex = 0;
			int tableCount = 0;
			while(rs.next()){
				try{
					String tableName = rs.getString("TABLE_NAME");
					System.out.println("tableName:"+tableName);
					
					//排除表
					if(executedTables.contains(tableName.toLowerCase())) continue;

					tableCount++;
					System.out.println(tableCount + "、" + tableName + " doing...");
					
					//表名
					sheet.mergeCells(0, rowIndex, 9, rowIndex);  //合并单元格,5数字要与表头的cell个数一致
					sheet.addCell(new Label(0, rowIndex, tableCount + "、" + tableName));
					rowIndex++;
					
					//表头
					sheet.addCell(new Label(0,rowIndex,"序号"));
					sheet.addCell(new Label(1,rowIndex,"字段名"));
					sheet.addCell(new Label(2,rowIndex,"字段类型"));
					sheet.addCell(new Label(3,rowIndex,"长度"));
					sheet.addCell(new Label(4,rowIndex,"整数位"));
					sheet.addCell(new Label(5,rowIndex,"小数位"));
					sheet.addCell(new Label(6,rowIndex,"允许空值"));
					sheet.addCell(new Label(7,rowIndex,"缺省值"));
					sheet.addCell(new Label(8,rowIndex,"备注说明"));
					sheet.addCell(new Label(9,rowIndex,"索引次数"));
					rowIndex++;
					
					PreparedStatement ps = null;
					ps = cn.prepareStatement(this.getSqlStr(tableName));
					ResultSet res = ps.executeQuery();
					int colCnt = res.getMetaData().getColumnCount();
					int recordIndex = 1;
					while (res.next()) {
						sheet.addCell(new Label(0,rowIndex,String.valueOf(recordIndex)));
						for (int i = 1; i <= colCnt; i++) {
							sheet.addCell(new Label(i,rowIndex,res.getString(i)));
						}
						recordIndex++;
						rowIndex++;
					}
					rowIndex += 2;
					res.close();
					ps.close();
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			rs.close();
			
			System.out.println("DONE");
			
			book.write();
			book.close();
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			try{
				if(cn != null) cn.close();
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		try{
			CreateMetadata md = new CreateMetadata();
			md.createTableMetadata("C:\\temp\\md.xls");
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
}


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据数据库名生成数据库结构说明 的相关文章

随机推荐

  • SDK 开发中见到的问题

    问题1 Could not build module MySDK 原因是 在pubulic的头文件中导入的头文件都需要导入到pubulic中 m文件中头文件不需要导入 问题2 Missing submodule subHeader 原因是
  • PyDev Eclipse使用技巧说明

    PyDev Package Explorer 创建项目 在开展工作之前 需要创建一个新的项目 在 Eclipse 菜单栏中 选择 File gt New gt Project gt Pydev gt Pydev Project 单击 Nex
  • 求函数【线段树】【2020牛客寒假算法基础集训营2】

    首先 这个区间很容易让人想到是区间操作 那么就是来推公式吧 我们从中不难发现 从两个值到四个值 可以是相当于 其中 两个 括号中的值是不是有点相似 我们是不是可以将它放在线段树上来进行维护了 include
  • CVPR 2022

    作者 cocoon 编辑 3D视觉开发者社区 前言 FAIR又出新作了 一篇 2020年代的卷积网络 的横空出世 让国内外CV圈的眼光都聚焦于此 不少大牛都纷纷下场参与讨论 研究团队以Transformer的一些设计原则以及训练技巧为标 尽
  • 引用与指针有什么区别?

    引用与指针有什么区别 指针和引用都是地址的概念 指针指向一块内存 它的内容是所指内存的地址 引用是某块内存的别名 程序为指针变量分配内存区域 而不为引用分配内存区域 指针使用时要在前加 引用可以直接使用 引用在定义时就被初始化 之后无法改变
  • Java 异常

    目录 1 自己不处理 交给调用者处理 1 1 throws 声明一个异常 1 2 throw 抛出一个异常 2 自己处理异常 2 1 try catch 2 2 try catch的常见问题 3 Throwable 的成员方法 4 自定义异
  • [2021.9.13][OpenGL ES 3.0编程指南]1 OpenGL ES 3.0简介

    1 1 OpenGL ES 3 0 OpenGL ES 3 0实现了具有可编程着色功能的图形管线 由两个规范组成 OpenGL ES 3 0 API规范和OpenGL ES着色语言3 0规范 图1 1展示了OpenGL ES 3 0 图形管
  • java网络编程01——网络基本概念

    阅读 java网络编程 等诸多资料个人所思所想读书笔记 1 网络 因特网 两种方式回答问题 其一是描述因特网的基本构成即构成因特网的基本硬件和软件组件 其二根据分布式应用提供服务的联网基础设施描述因特网 因特网是世界范围的计算机网络 即是一
  • 服务器光信号闪红灯是什么意思,路由器光信号闪红灯是什么意思

    现在不少宽带在安装之后还需要配备一个路由器用来接收光纤信号 在路由器上会有几个指示灯 如果你的路由器信号灯一直闪红灯知道是什么意思吗 一起来了解一下吧 闪红灯的意思 宽带 费 现在宽带基本都是后付费模式 因为 费的时间太 运营商直接关掉了宽
  • 矩阵通高效监管企业新媒体矩阵,账号集中管理与运营数据分析

    越来越多的企业在全网布局旗下账号 希望通过社媒传播矩阵 以内容连接产品与用户 达成增加销售线索或扩大品牌声量的目的 构建矩阵的优势在于 内容能多元发展 聚集不同平台流量 多种营销渠道自主掌控 分散单一平台传播风险 各平台账号间也能协同互补
  • JavaScript中Math.max()和Math.min()方法

    JavaScript中Math max 和Math min 方法 Math是JavaScript中的对象 不是构造函数 可以用来执行数学任务 1 Math max max 返回给定的一组数据中的最大值 但是不接收数组作为参数 参考用法
  • vue3.0 兼容ie浏览器

    vue3 0 兼容ie浏览器 安装babel polyfill npm install save babel polyfill 在main js里面引入 一定要在最上面 第一行 import babel polyfill 安装完成后会有ba
  • HTML页面结构

  • Unity实现点击显示不同UI

    在开发过程中经常遇到切换显示不同UI的需求 实现方案有2套 1 创建两个场景A B 在A中点击某个button后触发切换事件后加载B场景现在新的场景信息 优点 是逻辑简单 在不同的场景中创建对应的UI即可 缺点是当两个场景中有重复显示的模型
  • 高德地图JSAPIvue项目的使用

    最近在项目中使用高德地图JSAPI 遇到一些问题整理一下做个总和记录 希望能帮到看到文章的大家 1 关于引用 npm i amap amap jsapi loader save 然后创建好地图容器后引入地图 注意避坑的点 1 使用loca可
  • vue指令实现埋点

    1 自定义指令 import Vue from vue 自定义埋点指令 Vue directive track 钩子函数 只调用一次 指令第一次绑定到元素时调用 在这里可以进行一次性的初始化设置 el 指令所绑定的元素 可以用来直接操作 D
  • Linux 读文件 - readahead预读算法

    顺序读场景 intmain charc 4096 intin 1 in open news txt O RDONLY intindex 0 while read in c 4096 4096 printf index d len ld n
  • linux 内核 - ioctl 函数详解

    linux 内核 ioctl 函数详解 1 概念 ioctl 是设备驱动程序中设备控制接口函数 一个字符设备驱动通常会实现设备打开 关闭 读 写等功能 在一些需要细分的情境下 如果需要扩展新的功能 通常以增设 ioctl 命令的方式实现 在
  • leetcode 907. 子数组的最小值之和

    给定一个整数数组 arr 找到 min b 的总和 其中 b 的范围为 arr 的每个 连续 子数组 由于答案可能很大 因此 返回答案模 10 9 7 leetcode题目链接 示例 1 输入 arr 3 1 2 4 输出 17 解释 子数
  • 根据数据库名生成数据库结构说明

    根据数据库名生成数据库结构说明 package com cjm common import java io File import java io FileOutputStream import java sql Connection im