使用JDBC获取各数据库的Meta信息——表以及对应的列

Posted 方大帝的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用JDBC获取各数据库的Meta信息——表以及对应的列相关的知识,希望对你有一定的参考价值。

第一个是工具类, MapUtil.java

import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.Iterator;  
import java.util.List;  
import java.util.Map;  
import java.util.Set;  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  
  
/** 
 * map转换工具 
 */  
public class MapUtil {  
      
    /** 
     * 将List中的Key转换为小写 
     * @param list 返回新对象 
     * @return 
     */  
    public static List<Map<String, Object>> convertKeyList2LowerCase(List<Map<String, Object>> list){  
        if(null==list) {  
            return null;  
        }  
        List<Map<String, Object>> resultList = new ArrayList<Map<String,Object>>();  
        //  
        Iterator<Map<String, Object>> iteratorL = list.iterator();  
        while (iteratorL.hasNext()) {  
            Map<String, Object> map = (Map<String, Object>) iteratorL.next();  
            //  
            Map<String, Object> result = convertKey2LowerCase(map);  
            if(null != result){  
                resultList.add(result);  
            }  
        }  
        //  
        return resultList;  
    }  
    /** 
     * 转换单个map,将key转换为小写.  
     * @param map 返回新对象 
     * @return 
     */  
    public static Map<String, Object> convertKey2LowerCase(Map<String, Object> map){  
        if(null==map) {  
            return null;  
        }  
        Map<String, Object> result = new HashMap<String, Object>();  
        //  
        Set<String> keys  = map.keySet();  
        //  
        Iterator<String> iteratorK = keys.iterator();  
        while (iteratorK.hasNext()) {  
            String key = (String) iteratorK.next();  
            Object value = map.get(key);  
            if(null == key){  
                continue;  
            }  
            //  
            String keyL = key.toLowerCase();  
            result.put(keyL, value);  
        }  
        return result;  
    } 
}

然后是具体的实现工具类,使用了阿里巴巴的 fastjson 工具包;里面的测试类可以忽略

import java.sql.Connection;  
import java.sql.DatabaseMetaData;  
import java.sql.DriverManager;  
import java.sql.ResultSet;  
import java.sql.ResultSetMetaData;  
import java.sql.SQLException;  
import java.sql.Statement;  
import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.List;  
import java.util.Map;  
import java.util.Properties;  
  
import com.alibaba.fastjson.JSONArray;  
  
/** 
 * 需要注意,想要有表字段描述信息,获取连接时需要指定某些特殊属性<br/>  
 * 数据交换-工具类 
 */  
public class DBMSMetaUtil {  
  
  
    /** 
     * 数据库类型,枚举 
     *  
     */  
    public static enum DATABASETYPE {  
        ORACLE, mysql, SQLSERVER, SQLSERVER2005, DB2, INFORMIX, SYBASE, OTHER, EMPTY  
    }  
  
    /** 
     * 根据字符串,判断数据库类型 
     *  
     * @param databasetype 
     * @return 
     */  
    public static DATABASETYPE parseDATABASETYPE(String databasetype) {  
        // 空类型  
        if (null == databasetype || databasetype.trim().length() < 1) {  
            return DATABASETYPE.EMPTY;  
        }  
        // 截断首尾空格,转换为大写  
        databasetype = databasetype.trim().toUpperCase();  
        // Oracle数据库  
        if (databasetype.contains("ORACLE")) {  
            //  
            return DATABASETYPE.ORACLE;  
        }  
        // MYSQL 数据库  
        if (databasetype.contains("MYSQL")) {  
            //  
            return DATABASETYPE.MYSQL;  
        }  
        // SQL SERVER 数据库  
        if (databasetype.contains("SQL") && databasetype.contains("SERVER")) {  
            //  
            if (databasetype.contains("2005") || databasetype.contains("2008") || databasetype.contains("2012")) {  
  
                try {  
                    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");  
                } catch (ClassNotFoundException e) {  
                    e.printStackTrace();  
                }  
                  
                return DATABASETYPE.SQLSERVER2005;  
            } else {  
                try {  
                    // 注册 JTDS  
                    Class.forName("net.sourceforge.jtds.jdbc.Driver");  
                } catch (ClassNotFoundException e) {  
                    e.printStackTrace();  
                }  
                return DATABASETYPE.SQLSERVER;  
            }  
        }  
        // 下面的这几个没有经过实践测试, 判断可能不准确  
        // DB2 数据库  
        if (databasetype.contains("DB2")) {  
            //  
            return DATABASETYPE.DB2;  
        }  
        // INFORMIX 数据库  
        if (databasetype.contains("INFORMIX")) {  
            //  
            return DATABASETYPE.INFORMIX;  
        }  
        // SYBASE 数据库  
        if (databasetype.contains("SYBASE")) {  
            //  
            return DATABASETYPE.SYBASE;  
        }  
  
        // 默认,返回其他  
        return DATABASETYPE.OTHER;  
    }  
  
    /** 
     * 列出数据库的所有表 
     */  
    // 可以参考: http://www.cnblogs.com/chinafine/articles/1847205.html  
    public static List<Map<String, Object>> listTables(String databasetype, String ip, String port, String dbname,  
            String username, String password) {  
        // 去除首尾空格  
        databasetype = trim(databasetype);  
        ip = trim(ip);  
        port = trim(port);  
        dbname = trim(dbname);  
        username = trim(username);  
        password = trim(password);  
        //  
        DATABASETYPE dbtype = parseDATABASETYPE(databasetype);  
        //  
        List<Map<String, Object>> result = null;  
        String url = concatDBURL(dbtype, ip, port, dbname);  
        Connection conn = getConnection(url, username, password);  
        // Statement stmt = null;  
        ResultSet rs = null;  
        //  
        try {  
            // 这句话我也不懂是什么意思... 好像没什么用  
            conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);  
            // 获取Meta信息对象  
            DatabaseMetaData meta = conn.getMetaData();  
            // 数据库  
            String catalog = null;  
            // 数据库的用户  
            String schemaPattern = null;// meta.getUserName();  
            // 表名  
            String tableNamePattern = null;//  
            // types指的是table、view  
            String[] types = { "TABLE" };  
            // Oracle  
            if (DATABASETYPE.ORACLE.equals(dbtype)) {  
                schemaPattern = username;  
                if (null != schemaPattern) {  
                    schemaPattern = schemaPattern.toUpperCase();  
                }  
                // 查询  
                rs = meta.getTables(catalog, schemaPattern, tableNamePattern, types);  
            } else if (DATABASETYPE.MYSQL.equals(dbtype)) {  
                // Mysql查询  
                // MySQL 的 table 这一级别查询不到备注信息  
                schemaPattern = dbname;  
                rs = meta.getTables(catalog, schemaPattern, tableNamePattern, types);  
            }  else if (DATABASETYPE.SQLSERVER.equals(dbtype) || DATABASETYPE.SQLSERVER2005.equals(dbtype)) {  
                // SqlServer  
                tableNamePattern = "%";  
                rs = meta.getTables(catalog, schemaPattern, tableNamePattern, types);  
            }  else if (DATABASETYPE.DB2.equals(dbtype)) {  
                // DB2查询  
                schemaPattern = "jence_user";  
                tableNamePattern = "%";  
                rs = meta.getTables(catalog, schemaPattern, tableNamePattern, types);  
            } else if (DATABASETYPE.INFORMIX.equals(dbtype)) {  
                // SqlServer  
                tableNamePattern = "%";  
                rs = meta.getTables(catalog, schemaPattern, tableNamePattern, types);  
            } else if (DATABASETYPE.SYBASE.equals(dbtype)) {  
                // SqlServer  
                tableNamePattern = "%";  
                rs = meta.getTables(catalog, schemaPattern, tableNamePattern, types);  
            }  else {  
                throw new RuntimeException("不认识的数据库类型!");  
            }  
            //  
            result = parseResultSetToMapList(rs);  
  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            close(rs);  
            close(conn);  
        }  
        //  
        return result;  
    }  
  
    /** 
     * 列出表的所有字段 
     */  
    public static List<Map<String, Object>> listColumns(String databasetype, String ip, String port, String dbname,  
            String username, String password, String tableName) {  
        // 去除首尾空格  
        databasetype = trim(databasetype);  
        ip = trim(ip);  
        port = trim(port);  
        dbname = trim(dbname);  
        username = trim(username);  
        password = trim(password);  
        tableName = trim(tableName);  
        //  
        DATABASETYPE dbtype = parseDATABASETYPE(databasetype);  
        //  
        List<Map<String, Object>> result = null;  
        String url = concatDBURL(dbtype, ip, port, dbname);  
        Connection conn = getConnection(url, username, password);  
        // Statement stmt = null;  
        ResultSet rs = null;  
        //  
        try {  
            // 获取Meta信息对象  
            DatabaseMetaData meta = conn.getMetaData();  
            // 数据库  
            String catalog = null;  
            // 数据库的用户  
            String schemaPattern = null;// meta.getUserName();  
            // 表名  
            String tableNamePattern = tableName;//  
            // 转换为大写  
            if (null != tableNamePattern) {  
                tableNamePattern = tableNamePattern.toUpperCase();  
            }  
            //   
            String columnNamePattern = null;  
            // Oracle  
            if (DATABASETYPE.ORACLE.equals(dbtype)) {  
                // 查询  
                schemaPattern = username;  
                if (null != schemaPattern) {  
                    schemaPattern = schemaPattern.toUpperCase();  
                }  
            } else {  
                //  
            }  
  
            rs = meta.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);  
            // TODO 获取主键列,但还没使用  
            meta.getPrimaryKeys(catalog, schemaPattern, tableNamePattern);  
            //  
            result = parseResultSetToMapList(rs);  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            // 关闭资源  
            close(rs);  
            close(conn);  
        }  
        //  
        return result;  
    }  
  
    /** 
     * 根据IP,端口,以及数据库名字,拼接Oracle连接字符串 
     *  
     * @param ip 
     * @param port 
     * @param dbname 
     * @return 
     */  
    public static String concatDBURL(DATABASETYPE dbtype, String ip, String port, String dbname) {  
        //  
        String url = "";  
        // Oracle数据库  
        if (DATABASETYPE.ORACLE.equals(dbtype)) {  
            //  
            url += "jdbc:oracle:thin:@";  
            url += ip.trim();  
            url += ":" + port.trim();  
            url += ":" + dbname;  
              
            // 如果需要采用 hotbackup  
            String url2 = "";  
            url2 = url2+"jdbc:oracle:thin:@(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = "  
                    + ip.trim() +")(PORT ="+ port.trim() +")))(CONNECT_DATA = (SERVICE_NAME ="+dbname+  
                    ")(FAILOVER_MODE = (TYPE = SELECT)(METHOD = BASIC)(RETRIES = 180)(DELAY = 5))))";  
            //  
            // url = url2;  
        } else if (DATABASETYPE.MYSQL.equals(dbtype)) {  
            //  
            url += "jdbc:mysql://";  
            url += ip.trim();  
            url += ":" + port.trim();  
            url += "/" + dbname;  
        } else if (DATABASETYPE.SQLSERVER.equals(dbtype)) {  
            //  
            url += "jdbc:jtds:sqlserver://";  
            url += ip.trim();  
            url += ":" + port.trim();  
            url += "/" + dbname;  
            url += ";tds=8.0;lastupdatecount=true";  
        } else if (DATABASETYPE.SQLSERVER2005.equals(dbtype)) {  
            //  
            url += "jdbc:sqlserver://";  
            url += ip.trim();  
            url += ":" + port.trim();  
            url += "; DatabaseName=" + dbname;  
        } else if (DATABASETYPE.DB2.equals(dbtype)) {  
            url += "jdbc:db2://";  
            url += ip.trim();  
            url += ":" + port.trim();  
            url += "/" + dbname;  
        } else if (DATABASETYPE.INFORMIX.equals(dbtype)) {  
            // Infox mix 可能有BUG  
            url += "jdbc:informix-sqli://";  
            url += ip.trim();  
            url += ":" + port.trim();  
            url += "/" + dbname;  
            // +":INFORMIXSERVER=myserver;user="+bean.getDatabaseuser()+";password="+bean.getDatabasepassword()  
        } else if (DATABASETYPE.SYBASE.equals(dbtype)) {  
            url += "jdbc:sybase:Tds:";  
            url += ip.trim();  
            url += ":" + port.trim();  
            url += "/" + dbname;  
        } else {  
            throw new RuntimeException("不认识的数据库类型!");  
        }  
        //  
        return url;  
    }  
  
    /** 
     * 获取JDBC连接 
     *  
     * @param url 
     * @param username 
     * @param password 
     * @return 
     */  
    public static Connection getConnection(String url, String username, String password) {  
        Connection conn = null;  
        try {  
            // 不需要加载Driver. Servlet 2.4规范开始容器会自动载入  
            // conn = DriverManager.getConnection(url, username, password);  
            //  
            Properties info =new Properties();  
            //  
            info.put("user", username);  
            info.put("password", password);  
            // !!! Oracle 如果想要获取元数据 REMARKS 信息,需要加此参数  
            info.put("remarksReporting","true");  
            // !!! MySQL 标志位, 获取TABLE元数据 REMARKS 信息  
            info.put("useInformationSchema","true");  
            // 不知道SQLServer需不需要设置...  
            //  
            conn = DriverManager.getConnection(url, info);  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        return conn;  
    }  
  
    /** 
     * 将一个未处理的ResultSet解析为Map列表. 
     *  
     * @param rs 
     * @return 
     */  
    public static List<Map<String, Object>> parseResultSetToMapList(ResultSet rs) {  
        //  
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();  
        //  
        if (null == rs) {  
            return null;  
        }  
        //  
        try {  
            while (rs.next()) {  
                //   
                Map<String, Object> map = parseResultSetToMap(rs);  
                //  
                if (null != map) {  
                    result.add(map);  
                }  
            }  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        //  
        return result;  
    }  
  
    /** 
     * 解析ResultSet的单条记录,不进行 ResultSet 的next移动处理 
     *  
     * @param rs 
     * @return 
     */  
    private static Map<String, Object> parseResultSetToMap(ResultSet rs) {  
        //  
        if (null == rs) {  
            return null;  
        }  
        //  
        Map<String, Object> map = new HashMap<String, Object>();  
        //  
        try {  
            ResultSetMetaData meta = rs.getMetaData();  
            //  
            int colNum = meta.getColumnCount();  
            //  
            for (int i = 1; i <= colNum; i++) {  
                // 列名  
                String name = meta.getColumnLabel(i); // i+1  
                Object value = rs.getObject(i);  
                // 加入属性  
                map.put(name, value);  
            }  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        //  
        return map;  
    }  
      
    //  
    public static boolean TryLink(String databasetype, String ip, String port, String dbname, String username, String password) {  
        //  
        DATABASETYPE dbtype = parseDATABASETYPE(databasetype);  
        String url = concatDBURL(dbtype, ip, port, dbname);  
        Connection conn = null;  
        //  
        try {  
            conn = getConnection(url, username, password);  
            if(null == conn){  
                return false;  
            }  
            DatabaseMetaData meta =  conn.getMetaData();  
            //  
            if(null == meta){  
                return false;  
            } else {  
                // 只有这里返回true  
                return true;  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally{  
            close(conn);  
        }  
        //  
        return false;  
    }  
    //  
    public static void close(Connection conn) {  
        if(conn!=null) {  
            try {  
                conn.close();  
                conn = null;  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
    //  
    public static void close(Statement stmt) {  
        if(stmt!=null) {  
            try {  
                stmt.close();  
                stmt = null;  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
    //  
    public static void close(ResultSet rs) {  
        if(rs!=null) {  
            try {  
                rs.close();  
                rs = null;  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
    //  
    public static String trim(String str){  
        if(null != str){  
            str = str.trim();  
        }  
        return str;  
    }  
  
    public static void main(String[] args) {  
        //testLinkOracle();  
        //testLinkSQLServer();  
        testOracle();  
        //testMySQL();  
    }  
  
    //  
    public static void testLinkOracle() {  
        //  
        String ip= "192.168.0.100";  
        String port= "1521";   
        String dbname= "orcl";   
        String username= "username";   
        String password= "*****pwd";  
        String databasetype= "oracle";  
        //  
        String url = concatDBURL(parseDATABASETYPE(databasetype), ip, port, dbname);  
        System.out.println("url="+url);  
        //  
        boolean result = TryLink(databasetype, ip, port, dbname, username, password);  
        //  
        System.out.println("result="+result);  
    }  
  
    //  
    public static void testLinkSQLServer() {  
        //  
        String ip= "192.168.0.100";  
        String port= "1433";   
        String dbname= "sqlserverdb1";   
        String username= "sa";   
        String password= "186957";  
        String databasetype= "SQL Server";  
        //  
        String url = concatDBURL(parseDATABASETYPE(databasetype), ip, port, dbname);  
        System.out.println("url="+url);  
        //  
        boolean result = TryLink(databasetype, ip, port, dbname, username, password);  
        //  
        System.out.println("result="+result);  
    }  
      
      
      
    public static void testOracle() {  
        //  
        String ip = "192.168.0.100";  
        String port = "1521";  
        String dbname = "orcl";  
        String username = "unixsys";  
        String password = "orpass";  
        //  
        String databasetype = "Oracle";  
        // DATABASETYPE dbtype = parseDATABASETYPE(databasetype);  
        // System.out.println(DATABASETYPE.ORACLE.equals(dbtype));  
        //  
        String tableName = "DBMS_CODE_CHEME_NEW";  
  
        List<Map<String, Object>> tables = listTables(databasetype, ip, port, dbname, username, password);  
        List<Map<String, Object>> columns = listColumns(databasetype, ip, port, dbname, username, password, tableName);  
        //  
        tables = MapUtil.convertKeyList2LowerCase(tables);  
        columns = MapUtil.convertKeyList2LowerCase(columns);  
        //  
        String jsonT = JSONArray.toJSONString(tables, true);  
        System.out.println(jsonT);  
        System.out.println("tables.size()=" + tables.size());  
        //  
        System.out.println("-----------------------------------------" + "-----------------------------------------");  
        System.out.println("-----------------------------------------" + "-----------------------------------------");  
        //  
        String jsonC = JSONArray.toJSONString(columns, true);  
        System.out.println(jsonC);  
        System.out.println("columns.size()=" + columns.size());  
    }  
      
  
    public static void testMySQL() {  
        //  
        String ip = "127.0.0.1";  
        String port = "4050";  
        String   
            dbname = "

以上是关于使用JDBC获取各数据库的Meta信息——表以及对应的列的主要内容,如果未能解决你的问题,请参考以下文章

hbase读写流程

如何获取 JDBC 中所有表的主键?

jdbc读取数据库,表相关信息(含注释)

javaWeb_JDBC_利用反射以及JDBC元数据编写通用的查询方法

使用JDBC connect获取数据库表结构信息

HBase框架基础