注解详解
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "authors")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", length = 100, nullable = false)
private String name;
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
private List<Book> books;
// Constructors, getters, setters, and other methods
}
@Entity
@Table(name = "books")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title", length = 200, nullable = false)
private String title;
@ManyToOne
@JoinColumn(name = "author_id", referencedColumnName = "id")
private Author author;
// Constructors, getters, setters, and other methods
}
这里有一些关键点说明:
-
Author
类:
-
@Entity
: 表示这是一个JPA实体类。 -
@Table
: 指定数据库表的名称。 -
@Id
: 标识主键字段。 -
@GeneratedValue
: 指定主键生成策略。 -
@Column
: 指定属性与数据库表列的映射关系。 -
@OneToMany
: 声明一对多关系,指定了mappedBy
表示关系由Book
类的author
属性来维护。
-
Book
类:
-
@Entity
: 表示这是一个JPA实体类。 -
@Table
: 指定数据库表的名称。 -
@Id
: 标识主键字段。 -
@GeneratedValue
: 指定主键生成策略。 -
@Column
: 指定属性与数据库表列的映射关系。 -
@ManyToOne
: 声明多对一关系。 -
@JoinColumn
: 指定关联列的信息。
@Table
@Table
注解是用于配置实体与数据库表之间映射关系的注解。它提供了一些属性,可以用于定义表的各种属性,如表名、索引、唯一约束等。
以下是 @Table
注解的一些常用属性和详细解释:
-
name
属性:
- 作用: 指定数据库表的名称。
- 示例:
@Entity
@Table(name = "authors")
public class Author {
// ...
}
-
说明: 在上例中,
@Table(name = "authors")
表示将Author
实体映射到数据库中的 "authors" 表。
-
catalog
和schema
属性:
- 作用: 用于指定数据库的 catalog 和 schema。
- 示例:
@Entity
@Table(name = "authors", catalog = "library_db", schema = "public")
public class Author {
// ...
}
-
说明: 在上例中,
catalog
属性指定了数据库的 catalog(数据库目录),schema
属性指定了数据库的 schema(数据库模式)。
-
uniqueConstraints
属性:
- 作用: 用于定义表上的唯一约束。
- 示例:
@Entity
@Table(name = "authors", uniqueConstraints = @UniqueConstraint(columnNames = "email"))
public class Author {
// ...
}
-
说明: 在上例中,
uniqueConstraints
属性指定了在 "authors" 表上创建一个唯一约束,该约束包含一个名为 "email" 的列。
-
indexes
属性:
- 作用: 用于定义表上的索引。
- 示例:
@Entity
@Table(name = "authors", indexes = @Index(columnList = "last_name"))
public class Author {
// ...
}
-
说明: 在上例中,
indexes
属性指定了在 "authors" 表上创建一个索引,该索引包含一个名为 "last_name" 的列。
- *schema` 属性:
- 作用: 用于指定数据库表的 schema。
- 示例:
@Entity
@Table(name = "authors", schema = "public")
public class Author {
// ...
}
-
说明: 在上例中,
schema
属性指定了数据库表的 schema(数据库模式)。
@Column
注解是用于配置实体属性与数据库表列之间映射关系的注解。它提供了一些属性,可以用于定义列的各种属性,如列名、长度、是否可为空等。
@Column
-
name
属性:
- 作用: 指定数据库表列的名称。
- 示例:
@Entity
public class Author {
@Column(name = "full_name")
private String fullName;
// ...
}
-
说明: 在上例中,
@Column(name = "full_name")
表示将Author
实体的fullName
属性映射到数据库表的 "full_name" 列。
-
**nullable**
** 属性:**
- 作用: 指定列是否允许为null。
- 示例:
@Entity
public class Author {
@Column(nullable = false)
private String fullName;
// ...
}
-
说明: 在上例中,
@Column(nullable = false)
表示fullName
列不允许为null。
-
unique
属性:
- 作用: 指定列的值是否唯一。
- 示例:
@Entity
public class Author {
@Column(unique = true)
private String email;
// ...
}
-
说明: 在上例中,
@Column(unique = true)
表示email
列的值必须是唯一的。
-
length
属性:
- 作用: 指定列的长度。
- 示例:
@Entity
public class Author {
@Column(length = 50)
private String fullName;
// ...
}
-
说明: 在上例中,
@Column(length = 50)
表示fullName
列的长度为50。
-
precision
和scale
属性:
- 作用: 用于指定精度和小数位数(仅对浮点型有效)。
- 示例:
@Entity
public class Book {
@Column(precision = 10, scale = 2)
private BigDecimal price;
// ...
}
-
说明: 在上例中,
@Column(precision = 10, scale = 2)
表示price
列的精度为10,小数位数为2。
-
**columnDefinition**
** 属性:**
- 作用: 允许通过 SQL 片段定义完整的列定义。可拼接建表语句
- 示例:
@Entity
public class Book {
@Column(columnDefinition = "TEXT")
private String description;
@Column(name = "user",columnDefinition = "VARCHAR ( 32 ) COMMENT '操作人'")
private String user;
// ...
}
-
说明: 在上例中,
@Column(columnDefinition = "TEXT")
表示description
列的数据库定义为TEXT类型。
@Id
- 基本使用:
@Entity
public class Author {
@Id
private Long id;
// ...
}
在上例中,@Id
注解标识了 Author
实体类的 id
字段作为主键。
-
生成策略 (
**@GeneratedValue**
):
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// ...
}
通常与 @GeneratedValue
注解一起使用,用于指定主键的生成策略。GenerationType.IDENTITY
表示使用数据库的自增长策略。
- 复合主键(Composite Primary Key):
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Id
private String isbn;
// ...
}
在一些情况下,实体的主键可能由多个字段组成,这时可以在多个字段上都使用 @Id
注解,表示复合主键。
- 主键的类型:
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// ...
}
主键可以是任意 Java 数据类型,例如 Long
、String
、int
等。通常,主键类型应该是可序列化的,并且不可变。
- 自定义主键生成器:
@Entity
public class Book {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String id;
// ...
}
如果需要使用自定义的主键生成器,可以通过 @GeneratedValue
和 @GenericGenerator
注解来配置。
@OneToOne
@OneToOne
是 JPA 中用于建立一对一关联关系的注解。它用于标注两个实体之间的一对一关系,其中一个实体(称为拥有方)包含对另一个实体(称为被拥有方)的引用。这个注解通常用在两个实体类中的成员变量上,表示两个实体之间的关联。
拥有方(Owner):
@Entity
@Table(name = "member")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(mappedBy = "member", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private MemberInfo memberInfo;
// other fields, getters, setters, etc.
}
被拥有方(Inverse):
@Entity
@Table(name = "member_info")
public class MemberInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne
@JoinColumn(name = "member_id")
private Member member;
// other fields, getters, setters, etc.
}
在上面的示例中:
-
Member
实体是拥有方,通过@OneToOne
注解和mappedBy
属性表示这是一对一关系,并指定了被拥有方是memberInfo
。 -
MemberInfo
实体是被拥有方,通过@OneToOne
注解和@JoinColumn
注解表示这是一对一关系,指定了关联的外键列为member_id
。
注意事项:
- 一对一关系中,拥有方一般是含有外键的一方,而被拥有方则是被引用的一方。
- 使用
mappedBy
属性来指定被拥有方的属性,表示关系的维护交由被拥有方来负责。在上述例子中,Member
中的memberInfo
属性负责关系的维护。 -
@JoinColumn
注解用于指定关联关系的外键列的名称。
在实际应用中,一对一关系通常用于建模特殊的业务场景,例如,一个实体与另一个实体存在唯一对应关系,或者某个实体的一部分信息存储在另一个实体中等。
@OneToMany
@OneToMany
注解用于在JPA实体类中建立一对多的关系,表示一个实体对象包含多个另一种实体对象。这种关系通常用于描述父实体与子实体之间的关联,其中一个父实体对应多个子实体。
- 基本使用:
@Entity
public class Author {
@OneToMany(mappedBy = "author")
@BatchSize(size = 10) // 每次加载10个关联实体
private List<Book> books;
// ...
}
在上例中,@OneToMany
注解表示 Author
实体类拥有多个 Book
实体。mappedBy
属性指定了在 Book
实体类中维护关联关系的属性名为 "author"。
-
**cascade**
** 属性:**
@Entity
public class Author {
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
private List<Book> books;
// ...
}
cascade
属性用于指定级联操作的类型。在上例中,CascadeType.ALL
表示对 Author
实体的操作将级联到其关联的所有 Book
实体。
-
**fetch**
** 属性:**
@Entity
public class Author {
@OneToMany(mappedBy = "author", fetch = FetchType.LAZY)
private List<Book> books;
// ...
}
fetch
属性用于指定关联关系的加载策略。FetchType.LAZY
表示懒加载,只有在访问 books
属性时才会加载关联的 Book
实体。
-
**targetEntity**
** 属性:**
@Entity
public class Author {
@OneToMany(mappedBy = "author", targetEntity = Book.class)
private List<Book> books;
// ...
}
targetEntity
属性用于指定关联的实体类型。在上例中,指定了关联的实体类型为 Book
。
-
**orphanRemoval**
** 属性:**
@Entity
public class Author {
@OneToMany(mappedBy = "author", orphanRemoval = true)
private List<Book> books;
// ...
}
orphanRemoval
属性用于指定是否移除孤儿对象。如果设置为 true
,当从 books
列表中移除 Book
实体时,该 Book
实体将被从数据库中删除。
-
**mappedBy**
** 属性:**
@Entity
public class Book {
@ManyToOne
//@JoinColumn用于设置,关联的外键约束的字段(外键配置)。
@JoinColumn(name = "author_id")
private Author author;
// ...
}
在 @OneToMany
注解中,mappedBy
属性用于指定在关联的另一方实体中维护关联关系的属性。在上例中,mappedBy = "author"
表示关联关系由 Book
实体的 author
属性维护。
@ManyToOne
@ManyToOne
注解用于在JPA实体类中建立多对一的关系,表示一个实体对象属于另一种实体对象。这种关系通常用于描述子实体与父实体之间的关联,其中多个子实体对应一个父实体。
- 基本使用:
@Entity
public class Book {
@ManyToOne
@JoinColumn(name = "author_id")
private Author author;
// ...
}
在上例中,@ManyToOne
注解表示 Book
实体类属于一个 Author
实体。@JoinColumn
注解用于指定关联的外键列名为 "author_id"。
-
**optional**
** 属性:**
@Entity
public class Book {
@ManyToOne(optional = false)
@JoinColumn(name = "author_id")
private Author author;
// ...
}
optional
属性用于指定关联的实体是否可以为null。如果设置为 false
,表示 Book
实体必须关联一个非空的 Author
实体。
-
**fetch**
** 属性:**
@Entity
public class Book {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id")
private Author author;
// ...
}
fetch
属性用于指定关联关系的加载策略。FetchType.LAZY
表示懒加载,只有在访问 author
属性时才会加载关联的 Author
实体。
-
**targetEntity**
** 属性:**
@Entity
public class Book {
@ManyToOne(targetEntity = Author.class)
@JoinColumn(name = "author_id")
private Author author;
// ...
}
targetEntity
属性用于指定关联的实体类型。在上例中,指定了关联的实体类型为 Author
。
-
**cascade**
** 属性:**
@Entity
public class Book {
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "author_id")
private Author author;
// ...
}
cascade
属性用于指定级联操作的类型。在上例中,CascadeType.ALL
表示对 Book
实体的操作将级联到其关联的 Author
实体。
-
**mappedBy**
** 属性:**
@Entity
public class Author {
@OneToMany(mappedBy = "author")
private List<Book> books;
// ...
}
在 @ManyToOne
注解中,mappedBy
属性用于指定在关联的另一方实体中维护关联关系的属性。在上例中,mappedBy = "author"
表示关联关系由 Author
实体的 books
属性维护。
@ManyToMany
@ManyToMany
是 JPA 中用于建立多对多关联关系的注解。多对多关系表示两个实体之间的关系是多对多的,一个实体可以与多个其他实体关联,同样,一个实体也可以被多个其他实体关联。
实体类1:
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private Set<Course> courses = new HashSet<>();
// other fields, getters, setters, etc.
}
@JoinTable
注解用于定义多对多关联关系的关联表信息。在多对多关系中,由于涉及到中间表来存储关联关系,因此需要使用 @JoinTable
注解来指定中间表的相关信息。
-
name = "student_course"
:指定关联表的名称为 "student_course"。 -
joinColumns = @JoinColumn(name = "student_id")
:指定关联表中与当前实体(Student
实体)关联的外键列的信息。在这里,student_id
列将用于关联Student
实体。 -
inverseJoinColumns = @JoinColumn(name = "course_id")
:指定关联表中与关联实体(Course
实体)关联的外键列的信息。在这里,course_id
列将用于关联Course
实体。
简而言之,@JoinTable
注解定义了关联表的名称和与两个实体关联的外键列的信息。在这个例子中,"student_course" 表将包含 student_id
和 course_id
两列,用于关联 Student
实体和 Course
实体。
实体类2:
@Entity
@Table(name = "course")
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@ManyToMany(mappedBy = "courses")
private Set<Student> students = new HashSet<>();
// other fields, getters, setters, etc.
}
在上述示例中:
-
Student
实体和Course
实体之间建立了多对多的关系,Student
中的courses
属性表示一个学生可以选修多门课程,而Course
中的students
属性表示一门课程可以被多个学生选修。 - 使用
@ManyToMany
注解来表示多对多关系,cascade = CascadeType.ALL
表示级联操作,即当对一个实体进行操作时,关联的实体也会相应地进行相同的操作。 - 使用
@JoinTable
注解指定中间表的名称和关联的外键列。 - 在
Course
实体中使用mappedBy
属性指定关联关系的被拥有方,这是因为关系的维护交由Student
实体来处理。
注意事项:
- 多对多关系通常需要中间表来存储两个实体的关联关系,这个中间表称为关联表(Join Table)。
-
@JoinTable
注解用于指定关联表的信息,包括表的名称、关联的外键列等。 -
mappedBy
属性用于指定关联关系的被拥有方,表示关系的维护交由被拥有方来负责。 - 在查询时,可以通过
@Query
注解、QueryDSL
或者使用内置的方法来进行多对多关系的查询。
@Embedded
@Embeddable
注解是 JPA 中用于标识可嵌入对象(Embeddable)的注解。嵌入对象是将一个对象的属性嵌入到另一个对象中,使得这些属性不再形成一个独立的实体,而是成为包含它们的实体的一部分。
- 标识为可嵌入对象:
- 使用
@Embeddable
注解标识一个类,表示该类的实例可以被嵌入到其他实体中。
@Embeddable
public class Address {
@Column(name = "street")
private String street;
@Column(name = "city")
private String city;
}
- 嵌入对象的属性:
- 在
@Embeddable
标识的类中,定义需要嵌入的属性,可以使用@Column
注解进行属性的详细配置。
- 嵌入到实体中:
- 在包含该嵌入对象的实体类中使用
@Embedded
注解引入嵌入对象。 - 嵌入对象可以在多个实体中进行复用,减少了实体类的冗余代码。
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Embedded
private Address address;
}
- 嵌入对象的属性在实体表中:
- 当实体类中引入了嵌入对象后,嵌入对象的属性将成为实体表的一部分,而不再形成独立的表。
CREATE TABLE Person (
id BIGINT PRIMARY KEY,
name VARCHAR(255),
street VARCHAR(255),
city VARCHAR(50)
);
通过使用 @Embeddable
注解和@Embedded注解,可以将一组属性视为一个整体,并嵌入到其他实体中,提高了实体模型的灵活性和可维护性。
@Transient
使用 @Transient 注解标识实体类中的字段或方法,表示这些属性不会被持久化到数据库。