如何快速的为现有数据库建立数据字典?

大部分项目在验收时都需要向客户提供一份详细的数据字典,而编写数据字典是一件既耗时又耗力的事情。为了解决这个问题,提高工作效率,本人写了一个工具类。该工具类能够根据现有的数据库快速的生成对应的数据字典,它可以为我们完成80%的工作量,我们只需要做剩下的20%的工作就可以了。该工具类目前支持Oracle、SqlServer数据库,操作简单,快捷。

1、以下是部分关键代码:

public class MetadataUtil {
	private Connection cn = null;
	private String catalog = null;//SqlServer use
	private String schemaPattern = "AGENTSKY";//Oracle use
	
	public MetadataUtil()throws Exception{
		String driver = "oracle.jdbc.driver.OracleDriver";
   		String url = "jdbc:oracle:thin:@localhost:1521:CRM";
   		String uid = "agentsky";
   		String pwd = "agentsky";

   		Class.forName(driver);
	   	this.cn = DriverManager.getConnection(url,uid,pwd);
	}
	
	private String getTablePrimaryKeys(String tableName){
		try{
			DatabaseMetaData dbmd = cn.getMetaData();
			ResultSet rs = dbmd.getPrimaryKeys(catalog, schemaPattern, tableName);
			StringBuffer sb = new StringBuffer(",");
			while(rs.next()){
				sb.append(rs.getString("COLUMN_NAME") + ",");
			}
			rs.close();
			return sb.toString();
		}catch(Exception ex){
			return "";
		}
	}
	
	private boolean containFieldType(String fieldType){
		List types = new ArrayList();
		types.add("CHAR");
		types.add("NCHAR");
		types.add("NVARCHAR");
		types.add("VARCHAR");
		types.add("VARCHAR2");
		return types.contains(fieldType.toUpperCase());
	}
	
	/**
	 * 取得表的备注信息
	 */
	private Map<String, String> getTableComments()throws Exception{
		Map<String, String> colMap = new HashMap<String, String>();
		
		StringBuffer sb = new StringBuffer();
		sb.append("select TABLE_NAME,TABLE_TYPE,COMMENTS from user_tab_comments");
		
		PreparedStatement pstm = cn.prepareStatement(sb.toString());
		ResultSet rs = pstm.executeQuery();
		while(rs.next()){
			colMap.put(rs.getString("TABLE_NAME").toUpperCase(), rs.getString("COMMENTS"));
		}
	    rs.close();
	    pstm.close();
		
		return colMap;
	}
	
	/**
	 * 取得表字段的备注信息
	 */
	private Map<String, String> getColumnComments(String tableName)throws Exception{
		Map<String, String> colMap = new HashMap<String, String>();
		
		StringBuffer sb = new StringBuffer();
		sb.append(" select TABLE_NAME,COLUMN_NAME,COMMENTS from user_col_comments ");
		sb.append(" where upper(TABLE_NAME)=upper('" + tableName + "') ");
		
		PreparedStatement pstm = cn.prepareStatement(sb.toString());
		ResultSet rs = pstm.executeQuery();
		while(rs.next()){
			colMap.put(rs.getString("COLUMN_NAME").toUpperCase(), rs.getString("COMMENTS"));
		}
	    rs.close();
	    pstm.close();
		
		return colMap;
	}
	
	public void createTableMetadata(String fileName){
		try{
			if(fileName == null || fileName.trim().length() == 0){
				throw new IllegalArgumentException("argument fileName can not be null");
			}
			File file = new File(fileName);
			
			//delete old file
			if(file.exists() && file.isFile()) file.delete();
			
			//create sheet
			FileOutputStream out = new FileOutputStream(file);
			WritableWorkbook book = Workbook.createWorkbook(out);
			WritableSheet sheet = book.createSheet("数据字典",0);
			
			//表备注
			Map<String, String> tableMap = getTableComments();
			
			DatabaseMetaData dbmd = cn.getMetaData();
			String[] types = {"TABLE"};
			ResultSet rs = dbmd.getTables(catalog ,schemaPattern, null, types);
			int rowIndex = 0;
			int tableCount = 0;
			while(rs.next()){
				try{
					String tableName = rs.getString("TABLE_NAME");
					if(tableName.indexOf("=")!=-1) continue;
					
					tableCount++;
					System.out.println(tableCount + "、" + tableName + " doing...");
					
					//表字段备注信息
					Map<String, String> colMap = getColumnComments(tableName);
					
					//表备注
					String tableComment = tableMap.get(tableName);
					if(CommonUtil.isNotEmpty(tableComment)){
						tableComment = ":" + tableComment;
					}else{
						tableComment = CommonUtil.trim(tableComment);
					}
					
					//表名
					sheet.mergeCells(0,rowIndex,6,rowIndex);  //合并单元格,6数字要与表头的cell个数一致
					sheet.addCell(new Label(0,rowIndex,tableName + tableComment));
					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,"备注"));
					rowIndex++;
					
					//主键
					String strPrimaryKeys = getTablePrimaryKeys(tableName);
					
					Statement stm = cn.createStatement();
					stm.setMaxRows(1);
					ResultSet rsColumn = stm.executeQuery("select * from " + tableName);
					ResultSetMetaData rsmd = rsColumn.getMetaData();
					int recordIndex = 1;
					for(int i=1;i<=rsmd.getColumnCount();i++){
						sheet.addCell(new Label(0,rowIndex,String.valueOf(recordIndex))); //序号
						sheet.addCell(new Label(1,rowIndex,rsmd.getColumnName(i))); //字段名
						sheet.addCell(new Label(2,rowIndex,colMap.get(rsmd.getColumnName(i).toUpperCase()))); //描述
						
						//字段类型
						String fieldType = rsmd.getColumnTypeName(i);
						if(containFieldType(fieldType)){
							fieldType += "(" + String.valueOf(rsmd.getColumnDisplaySize(i)) + ")";
						}
						sheet.addCell(new Label(3,rowIndex,fieldType));
						
						//是否主键
						if(strPrimaryKeys.indexOf("," + rsmd.getColumnName(i) + ",") != -1){
							sheet.addCell(new Label(4,rowIndex,"Y"));
						}else{
							sheet.addCell(new Label(4,rowIndex,""));
						}
						
						//是否可空
						sheet.addCell(new Label(5,rowIndex,(rsmd.isNullable(i)==1)?"":"N"));
						
						//备注
						sheet.addCell(new Label(6,rowIndex,""));
						
						
						rowIndex++;
						recordIndex++;
					}
					rowIndex += 2;
					
					rsColumn.close();
					stm.close();
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			rs.close();
			
			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{
			System.out.println("start...");
			MetadataUtil md = new MetadataUtil();
			md.createTableMetadata("c:\\agentsky_audit.xls");
			System.out.println("end");
			
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
极佳SQL数据库修复大师10.0,支持MSSQL 7.0 2000 2005 2008 2008R2 2012 2014 2016 2017 支持各种ERP数据库 金蝶 速达 用友 管家婆等等基于MSSQL数据库。支持数据库无法附加 报错等故障。   支持 各种版本SQL数据库 质疑 置疑 断电损坏。   支持 SQL数据库损坏 无法附加 各种报错问题修复。   支持 SQL数据库 823 824 825页损坏等各类错误修复。   支持 MDF NDF文件修复 支持备份文件修复完美支持各种字符集,支持从MDF文件反删除记录。 支持 SQL数据库各种字段类型 支持压缩表 压缩页 压缩记录恢复 支持 sql数据库系统表报错 系统表不一致 断电非法关机坏道导致的可疑 置疑 数据库挂起等故障 支持 SQL数据库PFS GAM SGAM 页损坏 不是有效的数据库等 不是有效的文件头等恢复 支持 SQL数据库DBCC 无法修复的 数据库数据恢复 支持 SQL数据库被勒索病毒加密的数据恢复。(大多被加密数据库都是非完全加密) 支持 blob,image,xml, 跨页数据以及文本大字段恢复 支持 sql数据库多用户架构,以及NDF 文件组。 支持 保存表 数据 存储过程 触发器 视图 函数等元数据及用户数据 支持 保存为脚本或者直接连到SQL保存到SQL数据库 扫描勒索病毒数据库及 损坏严重的数据库 请选择 标准恢复模式 如果发现有表应该有数据但是标准恢复模式没有扫描到 或表数据乱码 或表记录很少 可以用高级恢复模式尝试。 如果两种恢复模式都看不到本应该有数据的表,可以联系我们进行人工恢复。 www.sql110.com www.sql119.com TEL 13510228421 QQ 1186505712
Oracle数据库数据字典是一个包含Oracle数据库中所有对象的元数据信息的特殊数据库对象。它存储了数据库中的表、视图、索引、约束、触发器等各种对象的定义和属性信息。 数据字典Oracle数据库的一个重要组成部分,它存储在数据文件中,和其他数据库对象一样可以被备份和恢复。数据字典的存储结构是基于表和索引的,这使得它可以高效地进行查询和检索。 通过查询数据字典,我们可以获取到数据库中的各种对象的定义、属性、依赖关系、统计信息等信息。这些信息对于数据库管理员和开发人员来说非常重要,可以帮助他们更好地理解和管理数据库。 在Oracle数据库中,我们可以使用SQL语句查询数据字典。例如,我们可以使用以下语句查询数据库中的表信息: SELECT table_name, tablespace_name, num_rows FROM dba_tables; 这个查询语句会返回数据库中的所有表的名称、所属表空间和行数。 此外,我们还可以使用数据字典来查询索引、视图、约束、触发器等对象的信息。通过查询数据字典,我们可以了解数据库中的对象之间的依赖关系,比如一个表被哪些视图引用、一个触发器对哪些表进行操作等。 总之,Oracle数据库数据字典是一个非常有用的工具,它存储了数据库中各种对象的元数据信息,可以帮助数据库管理员和开发人员更好地管理和理解数据库。通过查询数据字典,我们可以获取到数据库中的对象的定义、属性、依赖关系等信息,提供了非常重要的参考和帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值