getprimarykeys()返回resultset,字段名固定为“column_name”“key_seq”“pk_name”等,须按名取值而非索引;schema/table参数需适配数据库规则,空值导致静默失败。

DatabaseMetaData.getPrimaryKeys() 返回结果的字段含义必须手动映射
这个方法返回的是 ResultSet,不是现成的 POJO 或集合,字段名和顺序是 JDBC 规范定义的固定字符串(比如 "COLUMN_NAME"、"KEY_SEQ"、"PK_NAME"),不是数据库方言里的列名。很多人直接用 rs.getString(1) 硬编码索引,一旦驱动升级或实现有差异就出错。
正确做法是显式按列名取值:
ResultSet rs = metaData.getPrimaryKeys(null, schema, table);
while (rs.next()) {
String columnName = rs.getString("COLUMN_NAME");
short keySeq = rs.getShort("KEY_SEQ");
String pkName = rs.getString("PK_NAME"); // 可能为 null
}
-
schema参数在不同数据库中行为不一致:MySQL 通常填null或数据库名;PostgreSQL 必须填"public"或自定义 schema 名;Oracle 对大小写敏感,得用大写 -
table参数要和实际建表时的大小写一致——SQL Server 默认忽略大小写,但启用了区分大小写的排序规则时就会失败 - 返回结果按
"KEY_SEQ"升序排列,这是复合主键中列的定义顺序,不是字母序
空 schema 或 null 表名导致 ResultSet 为空但无异常
这属于“静默失败”:方法调用成功,ResultSet 也有效,但 rs.next() 始终返回 false。常见原因包括:
- 传了空字符串
""给schema或table—— JDBC 规范要求它们是null或合法标识符,空字符串不被识别 - PostgreSQL 下漏传
schema(比如只传null),默认不会 fallback 到"public",必须明确指定 - Oracle 中表名未用大写,而数据字典里存的是大写(除非建表时加了双引号)
建议先用 DatabaseMetaData.getTables(null, schema, table, new String[]{"TABLE"}) 验证表是否存在,再查主键。
getPrimaryKeys() 不返回自增列的生成策略信息
它只告诉你哪些列是主键,不说明是否是 GENERATED ALWAYS AS IDENTITY(PostgreSQL/DB2)、AUTO_INCREMENT(MySQL)或 SEQUENCE(Oracle)。例如 MySQL 的 id INT PRIMARY KEY AUTO_INCREMENT,这里只会返回 COLUMN_NAME="id",没有“是否自增”的字段。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
如果需要判断自增属性,得结合其他元数据:
- MySQL:查
ResultSet的getColumnTypeName()是否含"AUTO_INCREMENT"(部分驱动支持) - PostgreSQL:查询
pg_get_serial_sequence()或检查pg_attribute.attidentity - 通用方案:用
DatabaseMetaData.getColumns()查该列的"IS_AUTOINCREMENT"列值(JDBC 4.1+),但驱动支持度不一
多主键场景下 KEY_SEQ 和 PK_NAME 的实际意义
当一个表有复合主键(如 (order_id, item_seq)),KEY_SEQ 表示定义顺序(order_id 是 1,item_seq 是 2),不是物理存储顺序。而 PK_NAME 是约束名,可用于后续查约束详情(比如通过 getImportedKeys() 找外键引用关系)。
注意:PK_NAME 在某些嵌入式数据库(如 HSQLDB 内存模式)或旧版驱动中可能为 null,不能假设它一定存在。
真正容易被忽略的是:同一个主键约束下的所有列,PK_NAME 值相同;但不同约束(比如误建了两个主键)会导致多条记录且 PK_NAME 不同——虽然标准 SQL 不允许一张表有多个主键,但部分数据库(如 SQLite)允许用 CREATE TABLE ... PRIMARY KEY(...) + ALTER TABLE ADD CONSTRAINT ... PRIMARY KEY 操作绕过校验。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










