Java中获取自增主键需用PreparedStatement指定Statement.RETURN_GENERATED_KEYS,再调用getGeneratedKeys()读取ResultSet;必须用executeUpdate(),且ResultSet需rs.next()后用rs.getLong(1)获取。

在 Java 中使用 JDBC 插入数据后获取数据库自增主键(如 MySQL 的 AUTO_INCREMENT、PostgreSQL 的 SERIAL),关键在于调用 PreparedStatement 时传入参数 Statement.RETURN_GENERATED_KEYS,再通过 getGeneratedKeys() 方法提取结果。
1. 使用 RETURN_GENERATED_KEYS 参数执行插入
创建 PreparedStatement 时需显式指定返回生成的键,否则 getGeneratedKeys() 返回空结果集:
- MySQL、PostgreSQL、SQL Server 等主流数据库均支持该方式
- 不能用
Statement直接执行 SQL 字符串(除非手动调用executeUpdate(sql, Statement.RETURN_GENERATED_KEYS)) - 推荐使用带字段名的重载方法(如
new String[]{"id"}),更明确且兼容性更好
2. 正确读取生成的主键值
getGeneratedKeys() 返回一个 ResultSet,其列名和类型取决于数据库驱动实现。通常第一列就是主键值:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 调用
rs.next()移动到第一行(有且仅有一行) - 用
rs.getLong(1)或rs.getInt(1)读取(推荐long避免溢出) - 也可用列名:如
rs.getLong("id"),但需确保字段名与建表一致且驱动支持 - 注意:该
ResultSet不可重复遍历,未调用next()会抛异常
3. 完整示例(MySQL)
假设表结构:CREATE TABLE user (id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50))
立即学习“Java免费学习笔记(深入)”;
String sql = "INSERT INTO user (name) VALUES (?)";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
ps.setString(1, "Alice");
int affected = ps.executeUpdate(); // 必须是 executeUpdate
try (ResultSet rs = ps.getGeneratedKeys()) {
if (rs.next()) {
long id = rs.getLong(1); // 或 rs.getLong("id")
System.out.println("插入成功,主键为:" + id);
}
}
}
4. 注意事项与常见问题
-
必须用
executeUpdate():用execute()或executeQuery()无法触发主键返回机制 -
MySQL 需开启
useAffectedRows=false(默认已满足),否则某些版本可能影响主键获取 -
批量插入不适用:
executeBatch()后调用getGeneratedKeys()行为因驱动而异,多数只返回第一个语句的键,建议单条处理或改用其他方案(如 UUID、Snowflake) -
Oracle 需特殊处理:不支持
RETURN_GENERATED_KEYS,应使用RETURNING子句配合executeUpdate(sql, new String[]{"ID"})

















