通过JDBC连接取得数据库相关的元数据

今天突然想起之前从astah-professional专门画ER图的工具 的一个Sample中取得Java代码,相当棒的一段代码,只需要通过JDBC连接就可以得到数据库信息,主要是通过java.sql.DatabaseMetaData这个类实现。先记录下来分享一下!

1.  db.properties

driver=org.postgresql.Driver 
url=jdbc:postgresql://12.3.3.3:5432/test
username=1
password=3

2. 核心类JdbcUtils

public class JdbcUtils {
	Properties ps;

	boolean isInitialized;

	protected String driver;
	protected String url;
	protected String username;
	protected String password;

	protected ConnectionInfo connInfo;

	public static void main(String[] args) throws Exception {
		JdbcUtils j1 = new JdbcUtils();
		j1.process();
	}

	/**
	 * 
	 */
	public JdbcUtils() {
		try {
			this.init();
		} catch (IOException e) { 
			e.printStackTrace();
		}
	}

	protected void init() throws IOException {

		if(isInitialized) {
			return;
		}
		ps = new Properties();
		ps.load(JdbcUtils.class.getResourceAsStream("db.properties"));

		driver = ps.getProperty("driver");
		url = ps.getProperty("url");
		username = ps.getProperty("username");
		password = ps.getProperty("password");

		this.connInfo = new ConnectionInfo(this.url);

		isInitialized = true;

		System.out.println("Load configurations.");
	}

	/**
	 * 
	 * 
	 * @param executor
	 * @throws Exception
	 */
	public void process() throws Exception {

		Connection conn = getConnection();
		System.out.println("Has connected....");

		ResultSet rs = null;
		String tableName = "product"; 
		try {
			DatabaseMetaData meta = conn.getMetaData(); 

			//打印 引入该 表的所有外键
			try { 
				System.out.println("------- Print all foreigh key from table ‘" + tableName + "‘ --------");
				System.out.println("Seq	Table	Column(FK)");
				rs = meta.getExportedKeys(conn.getCatalog(), null, tableName);
				 while (rs.next()) {
				   String fkTableName = rs.getString("FKTABLE_NAME");
				   String fkColumnName = rs.getString("FKCOLUMN_NAME");
				   int fkSequence = rs.getInt("KEY_SEQ");
				   System.out.println(String.format("%d	%s	%s", fkSequence, fkTableName, fkColumnName));
				 }
				 System.out.println("");
			} finally {
				closeResultSet(rs);
			}

		        
			try {
			         //打印该库的所有表
				System.out.println("------- Print all table name in this database ‘" + this.connInfo.db + "‘------");
				String[] types = {"TABLE"};
				rs = meta.getTables(null, null, "%", types); 
				System.out.println(this.getTablesDetail("Table list", rs)); 
			} finally {
				closeResultSet(rs);
			} 

		    //
			try {
			 //打印 出该库所有外键的Drop脚本
				System.out.println("------- Print all table foreign keys drop scripts in this database ‘" + this.connInfo.db + "‘------");
				String[] types = {"TABLE"};
				rs = meta.getTables(null, null, "%", types); 
				collectAllTableFK(rs, meta); 
			} finally {
				closeResultSet(rs);
			}  

			//
			try {
			//打印 引入该 表的所有外键
				System.out.println("------- Print all tables which has foreign key from table ‘" + tableName + "‘------");
				rs = meta.getExportedKeys(conn.getCatalog(), null, tableName);
				System.out.println(this.getKeyDetail("Exported keys", rs));
			} finally {
				closeResultSet(rs);
			}

			try { 
			//打印该表的所有外键
				System.out.println("------- Print all tables which table ‘" + tableName + "‘ reference to.------");
				rs = meta.getImportedKeys(conn.getCatalog(), null, tableName);
				System.out.println(this.getKeyDetail("Imported keys", rs)); 
			} finally {
				closeResultSet(rs);
			}
		} finally {
			closeResultSet(rs);
			closeConnection(conn);
		} 
	}

	/**
	 * @param rs
	 */
	private void closeResultSet(ResultSet rs) {
		if(rs !=null) {
			try {
				rs.close();
			} catch (SQLException e) {
			}
		}
	}

	/**
	 * @param con
	 */
	private void closeConnection(Connection con) {
		if(con !=null) {
			try {
				con.close();
			} catch (SQLException e) {
			}
		}
	}

    /**
     * @param tables
     * @return
     * @throws SQLException
     */
    private String collectAllTableFK(ResultSet tables, DatabaseMetaData meta) throws SQLException {
    
    	Set<String> s = new HashSet<String>();
    	StringBuilder sb = new StringBuilder();
    	while(tables.next()) {  
    		String tn = tables.getString("TABLE_NAME"); 
    		String scm = tables.getString("TABLE_SCHEM");
    
    		ResultSet fks = meta.getExportedKeys(meta.getConnection().getCatalog(), null, tn);
    		String[] fkns = this.collectFK(tn, s, fks, new Transformer() { 
										    			public Object transform(Object o) {//table , fk
										    				return String.format("ALTER TABLE %s DROP CONSTRAINT %s;\n", 
										    									Array.get(o, 0), Array.get(o, 1));
										    			}
							    		});
    		if(fkns.length==0) {
    			continue;
    		}
    		String ds = String.format("%s: %s", tn, StringUtils.join(fkns, "\n"));
    		sb.append(StringUtils.join(fkns, "")); 
		} 
    
    	System.out.println("FK---------------\n" + sb.toString());
    
		return sb.toString();
   }

	private String[] collectFK(String table, Set<String> fks, ResultSet ekRS, Transformer transformer) throws SQLException {

		Set<String> s = new HashSet<String>();

		while(ekRS.next()) {
			String fktn = ekRS.getString("FKTABLE_NAME");
			String v = ekRS.getString("FK_NAME");
			s.add((String)transformer.transform(new String[] {fktn, v}));
		}
		ekRS.close();
		return  s.toArray(new String[s.size()]);
	}

 

	private String getTablesDetail(String head, ResultSet rs) throws SQLException {
		return this.getKeyDetail(head, rs, getTablesRsFields());
	}

	private String getKeyDetail(String head, ResultSet rs) throws SQLException {
		return this.getKeyDetail(head, rs, getKeysRsColumns());
	}

    private String getKeyDetail(String head, ResultSet rs, String[] cols) throws SQLException {

		StringBuilder sb = new StringBuilder();
		sb.append("--------" + head + "----------\n");
		while (rs.next()) { 
			sb.append("#\n");
			for (String s : cols) {
				try {
					sb.append(s).append("=").append(rs.getString(s)).append("\n");
				}catch(Exception e) {
					System.out.println("miss field:" + s);
				}

			}
		} 
		sb.append("--------\n");
		return sb.toString();
	}

	private String[] getTablesRsFields() {
		return new String[] {
				"TABLE_CAT",
				"TABLE_SCHEM",
				"TABLE_NAME",
				"TABLE_TYPE",
				"REMARKS"
//				"TYPE_CAT",
//				"TYPE_SCHEM",
//				"TYPE_NAME",
//				"SELF_REFERENCING_COL_NAME",
//				"REF_GENERATION"
		};
	}
	private String[] getKeysRsColumns() {
		return new String[] {
				"PKTABLE_CAT",
				"PKTABLE_SCHEM",
				"PKTABLE_NAME",
				"PKCOLUMN_NAME",
				"FKTABLE_CAT",
				"FKTABLE_SCHEM",
				"FKTABLE_NAME",
				"FKCOLUMN_NAME",
				"KEY_SEQ",
				"UPDATE_RULE",
				"DELETE_RULE",
				"FK_NAME",
				"PK_NAME",
				"DEFERRABILITY"
		};
	}

	/**
	 * @return
	 * @throws Exception
	 */
	protected Connection getConnection() throws Exception {

		Class.forName(driver);
		Connection conn = DriverManager.getConnection(url, username, password);
		return conn;
	}

	private static class ConnectionInfo {

		String port ;
		String ip ;
		String protocol ;
		String db ; 
		String dbtype ; 

		/**
		 * 
		 */
		public ConnectionInfo(String url ) {
			Pattern p = Pattern.compile("^(.*):(.*)://(.*):(.*)/(.*)$");
			Matcher m = p.matcher(url);

			if(m.find()) {
				protocol = m.group(1);
				dbtype = m.group(2);
				ip = m.group(3);
				port = m.group(4);
				db = m.group(5);
			}
		} 
	} 

}
时间: 2024-08-03 15:19:31

通过JDBC连接取得数据库相关的元数据的相关文章

JDBC连接不同数据库(从基础来了解耦合)

JDBC连接不同数据库的实现步骤: 一.在Myeclipse或者Eclipse中新建JavaProject,命名:JDBCTest: 二.在src目录下新建类:JDBC.java,同时输入包名:com.jdbc,同时在src目录下新建                 jdbc.properties配置文件: 三.建立一个jar文件,将不同厂商的数据库驱动文件放置在此目录下: 四.右键点击驱动文件,点击 Build Path --> add class path ,此时在引用类库中会出现数据库  

jdbc 连接mysql数据库

jdbc驱动到官网下载,放在jdk的相关目录下面,或者jar文件加入到工程下面 package test_mysql; import java.sql.*; import java.util.Set; public class testjdbc { public static Connection getConnection() throws ClassNotFoundException, SQLException{ String URL="jdbc:mysql://localhost:3306

Crystal Reports 2008(水晶报表) JDBC连接mysql数据库

在本blog中,主要介绍的是Crystal Reports 2008使用JDBC连接mysql数据库. 在连接之间,首先要确认你电脑上面都安装了mysql数据库. 其次,就是jdbc连接数据时候所使用的相关jar包. 接下来,就可以进行数据库的一些连接操作了. 对JDBC不是很了解的,可以到 完整java开发中JDBC连接数据库代码和步骤 了解相关的操作 1.打开Crystal Reports的数据专家 2.点击JDBC(JNDI)出现: 3.输入url和数据库类名,点击下一步: 4.输入pas

分页查询信息(使用jdbc连接mysql数据库实现分页查询任务)

         分页查询信息       使用jdbc连接mysql数据库实现分页查询任务 通过mysql数据库提供的分页机制,实现商品信息的分页查询功能,将查询到的信息显示到jsp页面上. 本项目时一个简单的运用eclipse+jdbc+mysql的小程序. 连接的数据库名称为db_database11,属性如下: 1.创建名为com.pmf.bean的包,包中是名为Product的类,用于封装商品信息. 全部代码如下: package com.pmf.bean; /** * 商品 * */

JDBC连接Oracle数据库

我记得大二的时候,我们上java课程,当时老师就说了JDBC这个东西,也没怎么好好学,直到现在,我也不直到JDBC是什么玩意,就知道这玩意可以从数据库提取数据,那么JDBC到底是什么呢? JDBC是Java DataBase Connectivity的缩写,含义意思是java数据库连接,不需要多解释了,我感觉! 那么我们如何去做这样子的一个连接呢?用过一次之后就会发现,其实很简单,记住几个步骤,还有就是导入必要的驱动包就可以了,下面是几个重要的步骤: 第一步,你的项目环境中必须要导入必要的数据库

(详细)JAVA使用JDBC连接MySQL数据库(1)- 软件

欢迎任何形式的转载,但请务必注明出处. 1.jdk 点击查看安装和环境配置教程 2.Eclipse 点击进入官网下载 注意下载完成打开.exe后,出现下图界面,有很多版本供选择 本人目前在学JSP所以安装的是Java EE版本,初学者可以选择第一个Java Developers版本 3.Mysql 点击进入官网下载 点击进入推荐安装教程+环境配置 下载页面注意事项 (虽然选项只有32位的,但下载完成后32位和64位都会安装) (上面的是在线安装,下面的是离线安装,建议选择离线安装) 系列文章 (

java jdbc 连接mysql数据库 实现增删改查

好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打交道非常基础的一个知识,也是比较接近底层的,在实际的工作中大家用得更多的其实还是比较成熟的框架,例如Hibernate.Mybatis. 但是作为这些成熟框架的底层的jdbc却也是我们应该去掌握的,只有了解了jdbc的增删改查,这样在以后如果有兴趣去研究Hibernate或者Mybatis的源代码的

JDBC连接MySQL数据库及演示样例

JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,能够为多种关系数据库提供统一訪问,它由一组用Java语言编写的类和接口组成.JDBC为数据库开发者提供了一个标准的API,据此能够构建更高级的工具和接口,使数据库开发者能够用纯 Java API 编写数据库应用程序,而且可跨平台执行,而且不受数据库供应商的限制.

JAVA使用JDBC连接MySQL数据库 二(2)

本文是对 <JAVA使用JDBC连接MySQL数据库 二>的改进. 上节使用的是PreparedStatement来执行数据库语句,但是preparedStatement需要传递一个sql语句参数,才能创建.然而,DBHelper类只是起到打开和关闭数据库的作用,所以sql语句是要放到应用层部分的,而不是放到DBHelper类中. 而statment不需要传递一个sql语句参数,就能创建. 修改部分如下: public class DBHelper { String driver = &quo