首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JDBC DatabaseMetaData 實戰:獲取 Oracle/MySQL 數據庫元數據完整指南

     編輯:Java 相關知識

前言

java.sql.DatabaseMetaData 接口提供了獲取數據庫結構信息的標準途徑:表、視圖、列、主鍵、外鍵、索引、數據類型等。本文詳細講解核心方法用法、Oracle 與 MySQL 參數差異、返回結果集分析,並提供完整可運行的工具類代碼。

一、獲取 DatabaseMetaData 實例

Connection conn = DriverManager.getConnection(url, user, password);
DatabaseMetaData dbmd = conn.getMetaData();

二、核心方法詳解

1. getTables - 獲取表/視圖信息

ResultSet getTables(String catalog, String schema, String tableName, String[] types)
  • catalog:目錄名。Oracle 為 null,MySQL 為數據庫名。
  • schema:模式名。Oracle 為用戶名(大寫),MySQL 為 null。
  • tableName:表名模式,% 表示所有。
  • types:類型數組,如 {"TABLE"}、{"VIEW"}、{"TABLE","VIEW"}。

常用返回列:TABLE_CAT、TABLE_SCHEM、TABLE_NAME、TABLE_TYPE、REMARKS。

2. getColumns - 獲取列信息

ResultSet getColumns(String catalog, String schema, String tableName, String columnName)

返回列包含:COLUMN_NAME、DATA_TYPE、TYPE_NAME、COLUMN_SIZE、NULLABLE、REMARKS、COLUMN_DEF、ORDINAL_POSITION、IS_AUTOINCREMENT 等。

3. getPrimaryKeys - 獲取主鍵

ResultSet getPrimaryKeys(String catalog, String schema, String tableName)

返回列:TABLE_CAT、TABLE_SCHEM、TABLE_NAME、COLUMN_NAME、KEY_SEQ、PK_NAME。必須指定 tableName。

4. getImportedKeys / getExportedKeys - 獲取外鍵

// 獲取指定表引用的外鍵(被引用表)
ResultSet getImportedKeys(String catalog, String schema, String tableName)
// 獲取引用指定表的外鍵(引用表)
ResultSet getExportedKeys(String catalog, String schema, String tableName)

返回列包含: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。

5. getTypeInfo - 獲取數據類型信息

ResultSet getTypeInfo()

返回當前數據庫支持的所有數據類型及其精度、字面值前後綴、是否可空等信息。

6. getCatalogs / getSchemas - 獲取目錄與模式列表

ResultSet getCatalogs()   // 返回目錄名列表(TABLE_CAT)
ResultSet getSchemas()    // 返回模式名列表(TABLE_SCHEM)

三、Oracle 與 MySQL 參數差異總結

參數OracleMySQL
catalognull數據庫名(或 null 使用連接默認庫)
schema用戶名(大寫)null
tableName大寫表名區分大小寫視配置而定

注意:Oracle 表名、列名、用戶名在數據字典中均存儲為大寫,查詢時必須使用大寫,否則無結果。

四、完整工具類代碼

import java.sql.*;
import java.util.*;

public class DbMetaUtil {
    private Connection conn;

    public DbMetaUtil(String url, String user, String pwd) throws SQLException {
        this.conn = DriverManager.getConnection(url, user, pwd);
    }

    // 獲取所有表名
    public List getTableNames(String schema, String... types) throws SQLException {
        DatabaseMetaData dbmd = conn.getMetaData();
        ResultSet rs = dbmd.getTables(null, schema, "%", types.length == 0 ? new String[]{"TABLE"} : types);
        List list = new ArrayList<>();
        while (rs.next()) list.add(rs.getString("TABLE_NAME"));
        return list;
    }

    // 獲取表所有列名
    public List getColumnNames(String schema, String tableName) throws SQLException {
        DatabaseMetaData dbmd = conn.getMetaData();
        ResultSet rs = dbmd.getColumns(null, schema, tableName, "%");
        List list = new ArrayList<>();
        while (rs.next()) list.add(rs.getString("COLUMN_NAME"));
        return list;
    }

    // 獲取主鍵列名
    public List getPrimaryKeys(String schema, String tableName) throws SQLException {
        DatabaseMetaData dbmd = conn.getMetaData();
        ResultSet rs = dbmd.getPrimaryKeys(null, schema, tableName);
        List list = new ArrayList<>();
        while (rs.next()) list.add(rs.getString("COLUMN_NAME"));
        return list;
    }

    // 獲取外鍵信息
    public List> getImportedKeys(String schema, String tableName) throws SQLException {
        DatabaseMetaData dbmd = conn.getMetaData();
        ResultSet rs = dbmd.getImportedKeys(null, schema, tableName);
        List> list = new ArrayList<>();
        while (rs.next()) {
            Map map = new HashMap<>();
            map.put("pkTable", rs.getString("PKTABLE_NAME"));
            map.put("pkColumn", rs.getString("PKCOLUMN_NAME"));
            map.put("fkTable", rs.getString("FKTABLE_NAME"));
            map.put("fkColumn", rs.getString("FKCOLUMN_NAME"));
            map.put("fkName", rs.getString("FK_NAME"));
            list.add(map);
        }
        return list;
    }

    public void close() throws SQLException { if (conn != null) conn.close(); }

    // 測試主方法
    public static void main(String[] args) throws Exception {
        // Oracle 示例
        DbMetaUtil oracle = new DbMetaUtil("jdbc:oracle:thin:@localhost:1521:ORCL", "SCOTT", "tiger");
        System.out.println("Oracle 表: " + oracle.getTableNames("SCOTT"));
        System.out.println("EMP 列: " + oracle.getColumnNames("SCOTT", "EMP"));
        System.out.println("EMP 主鍵: " + oracle.getPrimaryKeys("SCOTT", "EMP"));
        oracle.close();

        // MySQL 示例
        DbMetaUtil mysql = new DbMetaUtil("jdbc:mysql://localhost:3306/testdb", "root", "123456");
        System.out.println("MySQL 表: " + mysql.getTableNames(null));
        System.out.println("user 列: " + mysql.getColumnNames(null, "user"));
        mysql.close();
    }
}

五、常見問題與避坑指南

  • 參數大小寫:Oracle 必須大寫 schema 和 tableName;MySQL 視 lower_case_table_names 設置而定。
  • 權限問題:獲取其他用戶表信息需 SELECT ANY DICTIONARY 或 DBA 權限。
  • 性能優化:盡量縮小 tableName 模式範圍,避免全庫掃描。
  • 版本差異:不同 JDBC 驅動返回列可能不同,建議通過 ResultSetMetaData 動態獲取列名。
  • 連接池:生產環境請使用 HikariCP/Druid 等連接池管理連接。

DatabaseMetaData 是數據庫元數據編程的基石,掌握其跨數據庫差異,能構建通用的 Schema 管理、代碼生成、數據遷移等工具。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved