springboot入门-JPA(Java Persistence API)注解与实体类Model
在 Spring Boot 中,使用 JPA(Java Persistence API) 进行数据库操作时,实体类(Model)需要借助注解来定义与数据库表的映射关系。以下是 @Entity
、@Table
、@Id
、@Column
的详细说明:
1. @Entity
- 作用:
标记一个类为 JPA 实体,表示这个类对应数据库中的一张表。 - 包路径:
javax.persistence.Entity
(Java EE)或jakarta.persistence.Entity
(Jakarta EE)。 - 关键特性:
- 必须与
@Id
注解配合使用(标记主键字段)。 - 实体类必须有一个无参构造方法。
- 必须与
- 示例:
@Entity public class User {// 字段和注解... }
2. @Table
- 作用:
指定实体类对应的数据库表名。如果省略,默认表名为类名(如User
→ 表名user
,具体命名策略由方言决定)。 - 包路径:
javax.persistence.Table
或jakarta.persistence.Table
。 - 常用参数:
参数名 作用 示例 name
指定表名 @Table(name = "users")
schema
指定数据库模式(如 PostgreSQL 的 schema) @Table(schema = "public")
uniqueConstraints
定义联合唯一约束 @Table(uniqueConstraints = @UniqueConstraint(columnNames = {"email"}))
- 示例:
@Entity @Table(name = "users") // 类对应表名 users public class User {// ... }
3. @Id
- 作用:
标记实体类的主键字段。每个实体类必须有一个主键。 - 包路径:
javax.persistence.Id
或jakarta.persistence.Id
。 - 常见搭配:
@GeneratedValue
:指定主键生成策略。@Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主键(MySQL、PostgreSQL) private Long id;
- 主键生成策略:
策略 ( GenerationType
)描述 适用场景 IDENTITY
数据库自增(如 MySQL 的 AUTO_INCREMENT
)大多数关系型数据库 SEQUENCE
使用数据库序列(如 Oracle、PostgreSQL) 支持序列的数据库 TABLE
通过数据库表模拟序列 通用但性能较差 AUTO
自动选择策略(默认) 由 JPA 实现决定
4. @Column
- 作用:
定义字段与数据库列的映射关系。如果字段名与列名一致,可省略此注解。 - 包路径:
javax.persistence.Column
或jakarta.persistence.Column
。 - 常用参数:
参数名 作用 示例 name
指定列名 @Column(name = "user_name")
nullable
是否允许为 NULL
(默认true
)@Column(nullable = false)
unique
是否唯一约束(默认 false
)@Column(unique = true)
length
字段长度(仅对字符串有效) @Column(length = 100)
columnDefinition
自定义列定义(如 TEXT
、TIMESTAMP
)@Column(columnDefinition = "TEXT")
- 示例:
@Entity @Table(name = "users") public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "user_name", nullable = false, length = 50)private String name;@Column(unique = true, columnDefinition = "VARCHAR(255) COMMENT '邮箱地址'")private String email; }
5. 完整示例与数据库表映射
Java 实体类
@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "user_name", nullable = false, length = 50)private String name;@Column(unique = true)private String email;// Getter & Setter
}
生成的 MySQL 表结构
CREATE TABLE users (id BIGINT AUTO_INCREMENT PRIMARY KEY,user_name VARCHAR(50) NOT NULL,email VARCHAR(255) UNIQUE
);
6. 常见问题
(1) 字段名与列名不一致怎么办?
使用 @Column(name = "column_name")
显式指定列名。
(2) 如何设置字段默认值?
通过 columnDefinition
参数:
@Column(columnDefinition = "VARCHAR(100) DEFAULT 'unknown'")
private String status;
(3) 是否需要为所有字段添加 @Column
?
如果字段名与列名一致且无需额外配置,可以省略。
(4) 如何定义复合主键?
使用 @EmbeddedId
或 @IdClass
(需定义主键类),例如:
@Entity
public class OrderItem {@EmbeddedIdprivate OrderItemId id; // 复合主键类
}@Embeddable
public class OrderItemId implements Serializable {private Long orderId;private Long productId;
}
总结
注解 | 核心作用 | 关键参数 | 是否必需 |
---|---|---|---|
@Entity | 声明实体类 | 无 | 是 |
@Table | 定义表名 | name , schema | 否(默认用类名) |
@Id | 标记主键 | 无 | 是 |
@Column | 定义列属性 | name , nullable , unique | 否(默认匹配字段名) |
通过合理使用这些注解,可以精确控制 Java 实体类与数据库表之间的映射关系,确保数据操作的准确性和灵活性。