Oracle不支持自增主键,Java中用Statement.RETURN_GENERATED_KEYS获取主键值,实则是通过预建的SEQUENCE序列和TRIGGER触发器协同生成并返回。
Oracle不支持自增主键,Statement.RETURN_GENERATED_KEYS 本质是取序列+触发器生成的值
java里用 statement.return_generated_keys 拿oracle主键,不是因为oracle有auto_increment,而是靠你提前建好的序列(sequence)和触发器(trigger)。jdbc驱动只是在 executeupdate() 后,把触发器插入到 returning into 或隐式结果集里的值捞出来。没配序列和触发器,这个标志根本没用——连编译都过,但运行时一定返回空结果集。
- 必须确保表上有对应序列,且触发器逻辑正确(比如
BEFORE INSERT、赋值给:new.id) - 如果用的是 Oracle 12c+ 的 IDENTITY 列(
GENERATED ALWAYS AS IDENTITY),触发器可省,但 JDBC 驱动版本得 ≥ 12.2.0.1,否则仍拿不到 -
RETURN_GENERATED_KEYS在 Oracle 下只对INSERT有效,UPDATE或DELETE设了也白设
PreparedStatement 才能用 RETURN_GENERATED_KEYS,Statement 不行
很多人试 statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS) 发现 getGeneratedKeys() 返回空 ResultSet,问题就出在这儿:Oracle JDBC 驱动只在 PreparedStatement 上支持该特性。底层依赖 oracle.jdbc.OraclePreparedStatement 对 RETURNING 子句的封装,而普通 Statement 不走这条路。
- 必须用
connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) - SQL 语句不能拼接字段名或表名(预编译要求),否则抛
SQLException - 如果想指定返回哪一列,得用
prepareStatement(sql, new String[]{"id"}),但 Oracle 对列名大小写敏感——建表时用双引号定义的列(如"Id"),这里也得传"Id",否则查不到
拿到生成键后,getGeneratedKeys() 返回的 ResultSet 有坑
Oracle 返回的 ResultSet 不像 MySQL 那样默认带列名 GENERATED_KEY,它直接映射为原字段名(比如 ID),但类型可能是 java.math.BigDecimal(即使数据库是 NUMBER(19)),强转 int 或 long 会报 ClassCastException。
- 别用
rs.getInt(1)硬取,优先用rs.getBigDecimal("ID").longValue() - 如果用了
new String[]{"id"}指定列,rs.getString("id")可能返回null(驱动未映射别名),老实用索引rs.getBigDecimal(1) - 记得判空:
if (rs.next()) { ... },没触发器或序列异常时,rs.next()直接返回false
Oracle 12c+ IDENTITY 列 + JDBC 12.2+ 是最简路径,但得关掉触发器
如果你用的是 Oracle 12.1+ 且能改表结构,直接上 IDENTITY 列比维护序列+触发器省心。但要注意:旧触发器必须删掉,否则会冲突(触发器试图再赋值,报 ORA-04098)。
- 建表示例:
CREATE TABLE t (id NUMBER GENERATED ALWAYS AS IDENTITY, name VARCHAR2(50)) - 对应 JDBC 调用完全一样,但不用自己管序列名、触发器逻辑
- 低版本驱动(如 ojdbc7)会静默忽略
RETURN_GENERATED_KEYS,必须升级到 ojdbc8(12.2.0.1+)才真正支持 - 如果项目里混用多种 Oracle 版本,别盲目切 IDENTITY——11g 环境直接挂
最常被忽略的一点:Oracle 的 RETURN_GENERATED_KEYS 行为高度依赖驱动版本、数据库版本、建表方式三者匹配。调不通先查 ojdbc.jar 版本,再确认表结构是否真由 IDENTITY 或标准序列+触发器支撑,而不是盯着 Java 代码反复改 prepareStatement 参数。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










