Java中通过DatabaseMetaData获取表结构信息需先调用connection.getMetaData()获取实例,再用getColumns()查字段、getPrimaryKeys()查主键、getIndexInfo()查索引,无需写SQL,具备跨数据库兼容性。

在 Java 中,DatabaseMetaData 是 JDBC 提供的用于获取数据库元数据(如表结构、索引、主键、外键等)的核心接口。它通过 Connection 对象获取,无需执行 SQL 查询语句,即可安全、跨数据库地读取结构信息。
获取 DatabaseMetaData 实例
必须先建立数据库连接,再调用 connection.getMetaData():
Connection conn = DriverManager.getConnection(url, user, password); DatabaseMetaData meta = conn.getMetaData();
注意:不同数据库驱动对元数据方法的支持程度略有差异(如 PostgreSQL 对某些索引字段返回 null),建议结合 meta.supportsXXX() 方法判断能力。
查询表结构(列信息)
使用 getColumns() 获取指定表的所有字段定义:
立即学习“Java免费学习笔记(深入)”;
- 参数顺序为:
catalog(数据库名,可为null)、schemaPattern(模式名,如"public"或"dbo",支持通配符)、tableNamePattern(表名,支持通配符,如"user%")、columnNamePattern(列名,一般填"%") - 返回
ResultSet,每行代表一个列,关键列包括:
COLUMN_NAME(列名)、DATA_TYPE(SQL 类型码,如Types.VARCHAR)、TYPE_NAME(数据库具体类型名,如"varchar")、COLUMN_SIZE(长度)、NULLABLE(是否允许 NULL,1=可空,0=非空)、IS_NULLABLE(字符串"YES"/"NO")、REMARKS(注释,部分数据库支持) - 示例(查
users表所有列):
ResultSet rs = meta.getColumns(null, "%", "users", "%");
while (rs.next()) {
String colName = rs.getString("COLUMN_NAME");
int sqlType = rs.getInt("DATA_TYPE");
String typeName = rs.getString("TYPE_NAME");
int size = rs.getInt("COLUMN_SIZE");
String nullable = rs.getString("IS_NULLABLE");
String comment = rs.getString("REMARKS");
System.out.printf("%s %s(%d) %s %s%n", colName, typeName, size, nullable, comment);
}
获取主键与索引信息
主键用 getPrimaryKeys(),返回结果集含 TABLE_NAME、COLUMN_NAME、KEY_SEQ(序号,复合主键用)、PK_NAME(主键约束名):
ResultSet pkRs = meta.getPrimaryKeys(null, "%", "users");
while (pkRs.next()) {
System.out.println("PK column: " + pkRs.getString("COLUMN_NAME"));
}
索引用 getIndexInfo(),注意第 5 个参数 unique 设为 false 可同时查唯一和非唯一索引;返回字段包括:
INDEX_NAME(索引名)、COLUMN_NAME(索引列名)、ORDINAL_POSITION(列在索引中的位置)、ASC_OR_DESC(升/降序)、NON_UNIQUE(是否非唯一,true 表示非唯一索引):
- 若只关心唯一索引(含主键、唯一约束生成的索引),可设
unique = true - 某些数据库(如 MySQL)会将主键也作为索引返回,可通过
TYPE字段区分:DatabaseMetaData.tableIndexStatistic(统计信息)、tableIndexClustered(聚集索引)、tableIndexHashed等 - 示例(查 users 表所有索引):
ResultSet idxRs = meta.getIndexInfo(null, "%", "users", false, true);
while (idxRs.next()) {
String indexName = idxRs.getString("INDEX_NAME");
String colName = idxRs.getString("COLUMN_NAME");
String ascDesc = idxRs.getString("ASC_OR_DESC");
boolean nonUnique = idxRs.getBoolean("NON_UNIQUE");
System.out.printf("Index '%s': %s %s (non-unique=%s)%n",
indexName, colName, ascDesc, nonUnique);
}
其他常用元数据查询
除表和索引外,还可快速获取:
-
getTables(null, "%", "%", new String[]{"TABLE"}):列出所有普通表(过滤类型) -
getSchemas():获取可用 schema 列表(PostgreSQL/Oracle 常用) -
getCatalogs():获取 catalog(数据库名)列表(MySQL 中对应 database) -
getImportedKeys()和getExportedKeys():查外键关系 -
supportsGetGeneratedKeys():确认是否支持获取自增主键(影响Statement.RETURN_GENERATED_KEYS的使用)
实际开发中建议封装工具类统一处理 ResultSet 解析,并缓存元数据结果以避免重复调用开销。


















