今天突然想起之前从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);
}
}
}
}