纯 JDBC 不解析注解,也不支持通过注解定义主键策略;它仅执行 SQL、处理 ResultSet 等,不反射读取实体类注解,注解生效必须依赖 Hibernate 等 ORM 框架实现。

Java 实体类本身不直接参与 JDBC 的主键生成策略解析,注解(如 JPA 的 @Id + @GeneratedValue)是 ORM 框架(如 Hibernate、MyBatis-Plus)使用的元数据,**JDBC 作为底层 API 完全不识别这些注解**。所以严格来说:**纯 JDBC 不解析注解,也不支持通过注解定义主键策略**。
为什么 JDBC 不处理注解?
JDBC 是 Java 与数据库通信的规范接口,只负责执行 SQL、处理 ResultSet、管理连接等,它没有反射解析实体类、不加载注解、也不做对象映射。注解驱动的行为必须由上层框架实现。
常见注解及其实际生效场景
以下注解属于 JPA 规范(如 Hibernate 实现),仅在使用 ORM 框架时才被读取和生效:
- @Id:标识主键字段(Hibernate/MyBatis-Plus 等会据此生成 INSERT SQL)
-
@GeneratedValue(strategy = GenerationType.IDENTITY):对应 MySQL 的
AUTO_INCREMENT,插入后由数据库生成 ID,框架从Statement.getGeneratedKeys()获取 - @GeneratedValue(strategy = GenerationType.UUID):由框架(如 Hibernate)在内存生成 UUID,不依赖数据库
- @GeneratedValue(strategy = GenerationType.TABLE):用单独表模拟序列(MySQL 不原生支持序列,此策略较少用)
如果坚持用 JDBC,怎么实现类似效果?
你需要手动处理,而不是靠注解:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 对
AUTO_INCREMENT字段:执行INSERT INTO user(name) VALUES(?)后,调用PreparedStatement.getGeneratedKeys()获取数据库返回的 ID - 对 UUID 主键:Java 端生成
UUID.randomUUID().toString(),再作为参数传入 INSERT - 对雪花 ID(如 Twitter Snowflake):用第三方库(如
twitter-snowflake或mybatis-plus内置 ID 生成器)在插入前生成 long 型 ID
想让注解“生效”,必须引入 ORM 层
例如用 Hibernate:
<font size="2"><pre class="brush:php;toolbar:false;">@Entity<br>@Table(name = "user")<br>public class User {<br> @Id<br> @GeneratedValue(strategy = GenerationType.IDENTITY)<br> private Long id;<br><br> private String name;<br> // getter/setter...<br>}
然后通过 session.save(user),Hibernate 才会:
- 反射读取
@Id和@GeneratedValue - 生成带
id占位符的 INSERT 语句(或省略 id 字段) - 根据 strategy 调用
getGeneratedKeys()或生成 UUID - 将生成的 ID 回填到对象中
不复杂但容易忽略:注解只是“声明”,真正干活的是框架——JDBC 只是它们背后调用的工具人。

















