常用JPA注解解释

JPA注解主要解决什么?

JPA 注解主要是在告诉 Hibernate:

这个 Java 类对应什么表?

哪个字段对应哪个列?

谁是主键?

两张表什么关系?

保存前要做什么?

常见的JPA注解

第一组:定义"这个类对应数据库什么东西"

java 复制代码
@Entity
@Table(name = "lesson")
public class Lesson {
}

@Entity 表示这个类是一个JPA实体类,要和数据库产生映射关系。

@Table 表示这个Java类映射到数据库的 lesson 表。如果不写@Table,JPA 通常会根据实体类名推断表名。

第二组:主键相关

java 复制代码
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Id 表示数据库的主键

@GeneratedValue 表示ID 不由 Java 自己填写,让数据库生成。其中的strategy表示主键生成策略,GenerationType.IDENTITY表示生成策略为使用数据库自增主键。

第三组:数据库字段映射

java 复制代码
@Column(nullable = false, length = 20, columnDefinition = "TEXT")
private String name;

@Column 表示name是数据库的一列,而且有这些++要求(括号里的属性设置)++。

java 复制代码
@Column(nullable = false) //不能为空
@Column(unique = true) //数据库要求唯一
java 复制代码
@Transient
private String displayName;

@Transient 表示这个字段只在 Java 中使用,不存进数据库。所以数据库中也就没有displayName这个列。可以理解为@Transient = 不持久化。

第四组:实体之间的关系

对象实体之间不是孤立的,数据库的表之间也是有联系的,为了表示这些联系,会使用以下注释。

@ManyToOne

例如一个学生可以有很多节课,但是一节 Lesson 只属于一个 Student(一对一课程)。

所以在Lesson类中,定义:

java 复制代码
@ManyToOne
@JoinColumn(name = "student_id")
private Student student;

意思是很多 Lesson 可以指向同一个 Student。++Lesson(many) to Student (one)++

lesson通过student_id 这个外键与student表产生联系.

@JoinColumn

告诉JPA,student表与lesson表靠数据库里的那一列连接。在这个例子中,student与lesson两个表通过student_id连接

@OneToMany

一个学生对应多个课程

所以在Student类中,定义:

java 复制代码
@OneToMany(mappedBy = "student")
private List<Lesson> lessons;

意思是一个Student有很多Lesson。 ++Student (one) to Lesson (many)++

@OneToOne

例如一节 Lesson 对应一份最终 Feedback

所以在Feedback类中,定义:

java 复制代码
@OneToOne
@JoinColumn(name = "lesson_id")
private Lesson lesson;

意思是一节Lesson对应一个Feedback。Lesson (one)to Feedback (one)

@ManyToMany

例如一个老师可以教很多学生,一个学生也可以被很多老师教。

所以在Teacher类中,定义:

java 复制代码
@ManyToMany
@joinColumn(name = "student_id")
private Teacher teacher;

意思是一个Teacher对应多个Student,一个Student对应多个Teacher。Teacher(many)to Student (many)。





java 复制代码
@OneToMany(
    mappedBy = "student",
    cascade = CascadeType.ALL,
    orphanRemoval = true)
private List<Lesson> lessons;

mappedBy 可以理解为真正维护这个关系的是 Lesson 类里的student字段。

也就是

java 复制代码
class Lesson {

    @ManyToOne
    private Student student;
}

这里的student对象。

cascade意思大致是:对 Student 做某些数据库操作时,要不要连带影响它关联的 Lesson。

例如删除Student时,是否Lesson也跟着删除。这就是 cascade 涉及的问题。

常见参数:PERSIST 保存时连带保存

MERGE 更新时连带更新

REMOVE 删除时连带删除

ALL 全部

orphanRemoval大致表示:某个子对象从父对象关系中被移除后,要不要把数据库记录也删除。

fetch关系注解里经常:

java 复制代码
@ManyToOne(fetch = FetchType.LAZY)

或者:

java 复制代码
FetchType.EAGER

这是在控制:

关联的数据什么时候查。

例如查询 Lesson。

EAGER

查 Lesson 的同时:

复制代码
Lesson
+
Student

一起查出来。

LAZY

先只查:

复制代码
Lesson

等真的:

复制代码
lesson.getStudent()

时再去查 Student。

可以简单记:

复制代码
LAZY = 用到再查
EAGER = 一开始就查

第五组:字段类型

@Enumerated

项目中可能存在状态字段,表示某一对象或事物的状态。

例如反馈状态:

java 复制代码
public enum FeedbackStatus {
    DRAFT,
    SUBMITTED
}

实体里:

java 复制代码
@Enumerated(EnumType.STRING)
private FeedbackStatus status;

数据库可能存:

java 复制代码
DRAFT
SUBMITTED

@Lob 用来表示比较大的文本或二进制数据。

例如:

java 复制代码
@Lob
private String content;

过去经常用于大文本。

第六组:生命周期回调

java 复制代码
@PrePersist
@PreUpdate
private void normalizeAndValidate() {
	if (name != null) {
		name = name.trim();
	}

	if (name == null || name.isEmpty() || name.length() > 20) {
		throw new IllegalArgumentException("Student name must contain 1 to 20 characters");
	}

	if (notes != null && notes.length() > 200) {
		throw new IllegalArgumentException("Student notes must not exceed 200 characters");
	}

以上代码表示在插入和更改之前对学生姓名进行规范化检查。

@PrePersist

第一次 INSERT 数据库之前调用。

@PreUpdate

UPDATE 数据库之前调用。

类似还有:

java 复制代码
@PostPersist    新增后
@PostUpdate     更新后
@PreRemove      删除前
@PostRemove     删除后
@PostLoad       查询加载后

@Version

乐观锁:在多人同时修改数据时会使用到。解决两个人同时修改一条数据,后提交的人会不会无意间覆盖前一个人的修改的问题。

其他Spring Data JPA注解

@Query

例如:

java 复制代码
@Query("""
    select s
    from Student s
    where s.grade = :grade
""")
List<Student> findByGrade(String grade);

表示:

默认 Repository 方法满足不了,我自己写查询。

JPA 不等于完全不能自己写查询。

@Query

例如:

java 复制代码
@Query("""
    select s
    from Student s
    where s.grade = :grade
""")
List<Student> findByGrade(
    @Param("grade") String grade
);

负责:

把方法参数绑定到查询里的参数。

@Modifying

如果@Query不是 SELECT,而是:

java 复制代码
UPDATE
DELETE

通常还会:

复制代码
@Modifying

还有一类很重要,但不是 JPA 注解:校验 Jakarta Validation

java 复制代码
@NotBlank
@Size(max = 20)
private String name;

@NotBlank : 不允许空字符串。

@Size(max = 20) : 最长 20。

@NotNull : 不能是 null。

还有:

java 复制代码
@Min
@Max
@Email
@Pattern

以上注解负责Java层的数据校验,而像@Column(nullable = false)这种更多属于数据库映射和数据库约束。

Hibernate 注解

@Check 也是在加强数据约束。

Spring 事务

@Transactional

例如:

java 复制代码
@Transactional
public void submitFeedback(...) {

    saveFeedback();

    updateLessonStatus();

}

意思:这几个数据库操作作为一个整体。保障操作完整执行,防止出现Feedback 已经保存,但Lesson 没更新的情况,有了事物,任何一步失败,整个操作回滚。

相关推荐
Allen_LVyingbo2 小时前
医疗AI基础2026-构建可靠智能体的编程路径(上)
大数据·数据库·人工智能·python·自动化
疯狂打码的少年2 小时前
【数据库技术】多值依赖与第四范式(4NF)
数据库·笔记·算法
微软技术分享3 小时前
Ubuntu 本地部署Ollama+OpenWebUI教程
数据库·ubuntu·postgresql
ly76893 小时前
MySQL 自增主键耗尽:从原理到应急恢复
数据库·mysql·innodb·故障恢复·自增主键·主键设计
文人sec3 小时前
MySQL主库出问题了,从库怎么办?备库为什么会延迟好几个小时?
android·数据库·mysql
砚底藏山河4 小时前
【量化纯GET实战 #23】多股票相关性:用收益率看板块联动
java·数据库·python·金融·数据分析
Java小白笔记4 小时前
MySQL 8.0 常用内置函数用例
数据库·mysql·mybatis
ZGG0035 小时前
MySQL 索引详解:B+ 树、聚簇索引与最左前缀
java·数据库·mysql