注解詳解
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
}
這里有一些關(guān)鍵點(diǎn)說明:
-
Author類:
-
@Entity: 表示這是一個JPA實(shí)體類。 -
@Table: 指定數(shù)據(jù)庫表的名稱。 -
@Id: 標(biāo)識主鍵字段。 -
@GeneratedValue: 指定主鍵生成策略。 -
@Column: 指定屬性與數(shù)據(jù)庫表列的映射關(guān)系。 -
@OneToMany: 聲明一對多關(guān)系,指定了mappedBy表示關(guān)系由Book類的author屬性來維護(hù)。
-
Book類:
-
@Entity: 表示這是一個JPA實(shí)體類。 -
@Table: 指定數(shù)據(jù)庫表的名稱。 -
@Id: 標(biāo)識主鍵字段。 -
@GeneratedValue: 指定主鍵生成策略。 -
@Column: 指定屬性與數(shù)據(jù)庫表列的映射關(guān)系。 -
@ManyToOne: 聲明多對一關(guān)系。 -
@JoinColumn: 指定關(guān)聯(lián)列的信息。
@Table
@Table 注解是用于配置實(shí)體與數(shù)據(jù)庫表之間映射關(guān)系的注解。它提供了一些屬性,可以用于定義表的各種屬性,如表名、索引、唯一約束等。
以下是 @Table 注解的一些常用屬性和詳細(xì)解釋:
-
name屬性:
- 作用: 指定數(shù)據(jù)庫表的名稱。
- 示例:
@Entity
@Table(name = "authors")
public class Author {
// ...
}
-
說明: 在上例中,
@Table(name = "authors")表示將Author實(shí)體映射到數(shù)據(jù)庫中的 "authors" 表。
-
catalog和schema屬性:
- 作用: 用于指定數(shù)據(jù)庫的 catalog 和 schema。
- 示例:
@Entity
@Table(name = "authors", catalog = "library_db", schema = "public")
public class Author {
// ...
}
-
說明: 在上例中,
catalog屬性指定了數(shù)據(jù)庫的 catalog(數(shù)據(jù)庫目錄),schema屬性指定了數(shù)據(jù)庫的 schema(數(shù)據(jù)庫模式)。
-
uniqueConstraints屬性:
- 作用: 用于定義表上的唯一約束。
- 示例:
@Entity
@Table(name = "authors", uniqueConstraints = @UniqueConstraint(columnNames = "email"))
public class Author {
// ...
}
-
說明: 在上例中,
uniqueConstraints屬性指定了在 "authors" 表上創(chuàng)建一個唯一約束,該約束包含一個名為 "email" 的列。
-
indexes屬性:
- 作用: 用于定義表上的索引。
- 示例:
@Entity
@Table(name = "authors", indexes = @Index(columnList = "last_name"))
public class Author {
// ...
}
-
說明: 在上例中,
indexes屬性指定了在 "authors" 表上創(chuàng)建一個索引,該索引包含一個名為 "last_name" 的列。
- *schema` 屬性:
- 作用: 用于指定數(shù)據(jù)庫表的 schema。
- 示例:
@Entity
@Table(name = "authors", schema = "public")
public class Author {
// ...
}
-
說明: 在上例中,
schema屬性指定了數(shù)據(jù)庫表的 schema(數(shù)據(jù)庫模式)。
@Column 注解是用于配置實(shí)體屬性與數(shù)據(jù)庫表列之間映射關(guān)系的注解。它提供了一些屬性,可以用于定義列的各種屬性,如列名、長度、是否可為空等。
@Column
-
name屬性:
- 作用: 指定數(shù)據(jù)庫表列的名稱。
- 示例:
@Entity
public class Author {
@Column(name = "full_name")
private String fullName;
// ...
}
-
說明: 在上例中,
@Column(name = "full_name")表示將Author實(shí)體的fullName屬性映射到數(shù)據(jù)庫表的 "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屬性:
- 作用: 用于指定精度和小數(shù)位數(shù)(僅對浮點(diǎn)型有效)。
- 示例:
@Entity
public class Book {
@Column(precision = 10, scale = 2)
private BigDecimal price;
// ...
}
-
說明: 在上例中,
@Column(precision = 10, scale = 2)表示price列的精度為10,小數(shù)位數(shù)為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列的數(shù)據(jù)庫定義為TEXT類型。
@Id
- 基本使用:
@Entity
public class Author {
@Id
private Long id;
// ...
}
在上例中,@Id 注解標(biāo)識了 Author 實(shí)體類的 id 字段作為主鍵。
-
生成策略 (
**@GeneratedValue**):
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// ...
}
通常與 @GeneratedValue 注解一起使用,用于指定主鍵的生成策略。GenerationType.IDENTITY 表示使用數(shù)據(jù)庫的自增長策略。
- 復(fù)合主鍵(Composite Primary Key):
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Id
private String isbn;
// ...
}
在一些情況下,實(shí)體的主鍵可能由多個字段組成,這時可以在多個字段上都使用 @Id 注解,表示復(fù)合主鍵。
- 主鍵的類型:
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// ...
}
主鍵可以是任意 Java 數(shù)據(jù)類型,例如 Long、String、int 等。通常,主鍵類型應(yīng)該是可序列化的,并且不可變。
- 自定義主鍵生成器:
@Entity
public class Book {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String id;
// ...
}
如果需要使用自定義的主鍵生成器,可以通過 @GeneratedValue 和 @GenericGenerator 注解來配置。
@OneToOne
@OneToOne 是 JPA 中用于建立一對一關(guān)聯(lián)關(guān)系的注解。它用于標(biāo)注兩個實(shí)體之間的一對一關(guān)系,其中一個實(shí)體(稱為擁有方)包含對另一個實(shí)體(稱為被擁有方)的引用。這個注解通常用在兩個實(shí)體類中的成員變量上,表示兩個實(shí)體之間的關(guān)聯(lián)。
擁有方(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實(shí)體是擁有方,通過@OneToOne注解和mappedBy屬性表示這是一對一關(guān)系,并指定了被擁有方是memberInfo。 -
MemberInfo實(shí)體是被擁有方,通過@OneToOne注解和@JoinColumn注解表示這是一對一關(guān)系,指定了關(guān)聯(lián)的外鍵列為member_id。
注意事項(xiàng):
- 一對一關(guān)系中,擁有方一般是含有外鍵的一方,而被擁有方則是被引用的一方。
- 使用
mappedBy屬性來指定被擁有方的屬性,表示關(guān)系的維護(hù)交由被擁有方來負(fù)責(zé)。在上述例子中,Member中的memberInfo屬性負(fù)責(zé)關(guān)系的維護(hù)。 -
@JoinColumn注解用于指定關(guān)聯(lián)關(guān)系的外鍵列的名稱。
在實(shí)際應(yīng)用中,一對一關(guān)系通常用于建模特殊的業(yè)務(wù)場景,例如,一個實(shí)體與另一個實(shí)體存在唯一對應(yīng)關(guān)系,或者某個實(shí)體的一部分信息存儲在另一個實(shí)體中等。
@OneToMany
@OneToMany 注解用于在JPA實(shí)體類中建立一對多的關(guān)系,表示一個實(shí)體對象包含多個另一種實(shí)體對象。這種關(guān)系通常用于描述父實(shí)體與子實(shí)體之間的關(guān)聯(lián),其中一個父實(shí)體對應(yīng)多個子實(shí)體。
- 基本使用:
@Entity
public class Author {
@OneToMany(mappedBy = "author")
@BatchSize(size = 10) // 每次加載10個關(guān)聯(lián)實(shí)體
private List<Book> books;
// ...
}
在上例中,@OneToMany 注解表示 Author 實(shí)體類擁有多個 Book 實(shí)體。mappedBy 屬性指定了在 Book 實(shí)體類中維護(hù)關(guān)聯(lián)關(guān)系的屬性名為 "author"。
-
**cascade**** 屬性:**
@Entity
public class Author {
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
private List<Book> books;
// ...
}
cascade 屬性用于指定級聯(lián)操作的類型。在上例中,CascadeType.ALL 表示對 Author 實(shí)體的操作將級聯(lián)到其關(guān)聯(lián)的所有 Book 實(shí)體。
-
**fetch**** 屬性:**
@Entity
public class Author {
@OneToMany(mappedBy = "author", fetch = FetchType.LAZY)
private List<Book> books;
// ...
}
fetch 屬性用于指定關(guān)聯(lián)關(guān)系的加載策略。FetchType.LAZY 表示懶加載,只有在訪問 books 屬性時才會加載關(guān)聯(lián)的 Book 實(shí)體。
-
**targetEntity**** 屬性:**
@Entity
public class Author {
@OneToMany(mappedBy = "author", targetEntity = Book.class)
private List<Book> books;
// ...
}
targetEntity 屬性用于指定關(guān)聯(lián)的實(shí)體類型。在上例中,指定了關(guān)聯(lián)的實(shí)體類型為 Book。
-
**orphanRemoval**** 屬性:**
@Entity
public class Author {
@OneToMany(mappedBy = "author", orphanRemoval = true)
private List<Book> books;
// ...
}
orphanRemoval 屬性用于指定是否移除孤兒對象。如果設(shè)置為 true,當(dāng)從 books 列表中移除 Book 實(shí)體時,該 Book 實(shí)體將被從數(shù)據(jù)庫中刪除。
-
**mappedBy**** 屬性:**
@Entity
public class Book {
@ManyToOne
//@JoinColumn用于設(shè)置,關(guān)聯(lián)的外鍵約束的字段(外鍵配置)。
@JoinColumn(name = "author_id")
private Author author;
// ...
}
在 @OneToMany 注解中,mappedBy 屬性用于指定在關(guān)聯(lián)的另一方實(shí)體中維護(hù)關(guān)聯(lián)關(guān)系的屬性。在上例中,mappedBy = "author" 表示關(guān)聯(lián)關(guān)系由 Book 實(shí)體的 author 屬性維護(hù)。
@ManyToOne
@ManyToOne 注解用于在JPA實(shí)體類中建立多對一的關(guān)系,表示一個實(shí)體對象屬于另一種實(shí)體對象。這種關(guān)系通常用于描述子實(shí)體與父實(shí)體之間的關(guān)聯(lián),其中多個子實(shí)體對應(yīng)一個父實(shí)體。
- 基本使用:
@Entity
public class Book {
@ManyToOne
@JoinColumn(name = "author_id")
private Author author;
// ...
}
在上例中,@ManyToOne 注解表示 Book 實(shí)體類屬于一個 Author 實(shí)體。@JoinColumn 注解用于指定關(guān)聯(lián)的外鍵列名為 "author_id"。
-
**optional**** 屬性:**
@Entity
public class Book {
@ManyToOne(optional = false)
@JoinColumn(name = "author_id")
private Author author;
// ...
}
optional 屬性用于指定關(guān)聯(lián)的實(shí)體是否可以為null。如果設(shè)置為 false,表示 Book 實(shí)體必須關(guān)聯(lián)一個非空的 Author 實(shí)體。
-
**fetch**** 屬性:**
@Entity
public class Book {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id")
private Author author;
// ...
}
fetch 屬性用于指定關(guān)聯(lián)關(guān)系的加載策略。FetchType.LAZY 表示懶加載,只有在訪問 author 屬性時才會加載關(guān)聯(lián)的 Author 實(shí)體。
-
**targetEntity**** 屬性:**
@Entity
public class Book {
@ManyToOne(targetEntity = Author.class)
@JoinColumn(name = "author_id")
private Author author;
// ...
}
targetEntity 屬性用于指定關(guān)聯(lián)的實(shí)體類型。在上例中,指定了關(guān)聯(lián)的實(shí)體類型為 Author。
-
**cascade**** 屬性:**
@Entity
public class Book {
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "author_id")
private Author author;
// ...
}
cascade 屬性用于指定級聯(lián)操作的類型。在上例中,CascadeType.ALL 表示對 Book 實(shí)體的操作將級聯(lián)到其關(guān)聯(lián)的 Author 實(shí)體。
-
**mappedBy**** 屬性:**
@Entity
public class Author {
@OneToMany(mappedBy = "author")
private List<Book> books;
// ...
}
在 @ManyToOne 注解中,mappedBy 屬性用于指定在關(guān)聯(lián)的另一方實(shí)體中維護(hù)關(guān)聯(lián)關(guān)系的屬性。在上例中,mappedBy = "author" 表示關(guān)聯(lián)關(guān)系由 Author 實(shí)體的 books 屬性維護(hù)。
@ManyToMany
@ManyToMany 是 JPA 中用于建立多對多關(guān)聯(lián)關(guān)系的注解。多對多關(guān)系表示兩個實(shí)體之間的關(guān)系是多對多的,一個實(shí)體可以與多個其他實(shí)體關(guān)聯(lián),同樣,一個實(shí)體也可以被多個其他實(shí)體關(guān)聯(lián)。
實(shí)體類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 注解用于定義多對多關(guān)聯(lián)關(guān)系的關(guān)聯(lián)表信息。在多對多關(guān)系中,由于涉及到中間表來存儲關(guān)聯(lián)關(guān)系,因此需要使用 @JoinTable 注解來指定中間表的相關(guān)信息。
-
name = "student_course":指定關(guān)聯(lián)表的名稱為 "student_course"。 -
joinColumns = @JoinColumn(name = "student_id"):指定關(guān)聯(lián)表中與當(dāng)前實(shí)體(Student實(shí)體)關(guān)聯(lián)的外鍵列的信息。在這里,student_id列將用于關(guān)聯(lián)Student實(shí)體。 -
inverseJoinColumns = @JoinColumn(name = "course_id"):指定關(guān)聯(lián)表中與關(guān)聯(lián)實(shí)體(Course實(shí)體)關(guān)聯(lián)的外鍵列的信息。在這里,course_id列將用于關(guān)聯(lián)Course實(shí)體。
簡而言之,@JoinTable 注解定義了關(guān)聯(lián)表的名稱和與兩個實(shí)體關(guān)聯(lián)的外鍵列的信息。在這個例子中,"student_course" 表將包含 student_id 和 course_id 兩列,用于關(guān)聯(lián) Student 實(shí)體和 Course 實(shí)體。
實(shí)體類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實(shí)體和Course實(shí)體之間建立了多對多的關(guān)系,Student中的courses屬性表示一個學(xué)生可以選修多門課程,而Course中的students屬性表示一門課程可以被多個學(xué)生選修。 - 使用
@ManyToMany注解來表示多對多關(guān)系,cascade = CascadeType.ALL表示級聯(lián)操作,即當(dāng)對一個實(shí)體進(jìn)行操作時,關(guān)聯(lián)的實(shí)體也會相應(yīng)地進(jìn)行相同的操作。 - 使用
@JoinTable注解指定中間表的名稱和關(guān)聯(lián)的外鍵列。 - 在
Course實(shí)體中使用mappedBy屬性指定關(guān)聯(lián)關(guān)系的被擁有方,這是因?yàn)殛P(guān)系的維護(hù)交由Student實(shí)體來處理。
注意事項(xiàng):
- 多對多關(guān)系通常需要中間表來存儲兩個實(shí)體的關(guān)聯(lián)關(guān)系,這個中間表稱為關(guān)聯(lián)表(Join Table)。
-
@JoinTable注解用于指定關(guān)聯(lián)表的信息,包括表的名稱、關(guān)聯(lián)的外鍵列等。 -
mappedBy屬性用于指定關(guān)聯(lián)關(guān)系的被擁有方,表示關(guān)系的維護(hù)交由被擁有方來負(fù)責(zé)。 - 在查詢時,可以通過
@Query注解、QueryDSL或者使用內(nèi)置的方法來進(jìn)行多對多關(guān)系的查詢。
@Embedded
@Embeddable 注解是 JPA 中用于標(biāo)識可嵌入對象(Embeddable)的注解。嵌入對象是將一個對象的屬性嵌入到另一個對象中,使得這些屬性不再形成一個獨(dú)立的實(shí)體,而是成為包含它們的實(shí)體的一部分。
- 標(biāo)識為可嵌入對象:
- 使用
@Embeddable注解標(biāo)識一個類,表示該類的實(shí)例可以被嵌入到其他實(shí)體中。
@Embeddable
public class Address {
@Column(name = "street")
private String street;
@Column(name = "city")
private String city;
}
- 嵌入對象的屬性:
- 在
@Embeddable標(biāo)識的類中,定義需要嵌入的屬性,可以使用@Column注解進(jìn)行屬性的詳細(xì)配置。
- 嵌入到實(shí)體中:
- 在包含該嵌入對象的實(shí)體類中使用
@Embedded注解引入嵌入對象。 - 嵌入對象可以在多個實(shí)體中進(jìn)行復(fù)用,減少了實(shí)體類的冗余代碼。
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Embedded
private Address address;
}
- 嵌入對象的屬性在實(shí)體表中:
- 當(dāng)實(shí)體類中引入了嵌入對象后,嵌入對象的屬性將成為實(shí)體表的一部分,而不再形成獨(dú)立的表。
CREATE TABLE Person (
id BIGINT PRIMARY KEY,
name VARCHAR(255),
street VARCHAR(255),
city VARCHAR(50)
);
通過使用 @Embeddable 注解和@Embedded注解,可以將一組屬性視為一個整體,并嵌入到其他實(shí)體中,提高了實(shí)體模型的靈活性和可維護(hù)性。
@Transient
使用 @Transient 注解標(biāo)識實(shí)體類中的字段或方法,表示這些屬性不會被持久化到數(shù)據(jù)庫。