Spring Data Jpa (二)

注解詳解

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)說明:

  1. 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ù)。
  1. 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ì)解釋:

  1. name屬性:
  • 作用: 指定數(shù)據(jù)庫表的名稱。
  • 示例:
@Entity
@Table(name = "authors")
public class Author {
    // ...
}
  • 說明: 在上例中,@Table(name = "authors") 表示將 Author 實(shí)體映射到數(shù)據(jù)庫中的 "authors" 表。
  1. catalogschema 屬性:
  • 作用: 用于指定數(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ù)庫模式)。
  1. uniqueConstraints 屬性:
  • 作用: 用于定義表上的唯一約束。
  • 示例:
@Entity
@Table(name = "authors", uniqueConstraints = @UniqueConstraint(columnNames = "email"))
public class Author {
    // ...
}
  • 說明: 在上例中,uniqueConstraints 屬性指定了在 "authors" 表上創(chuàng)建一個唯一約束,該約束包含一個名為 "email" 的列。
  1. indexes 屬性:
  • 作用: 用于定義表上的索引。
  • 示例:
@Entity
@Table(name = "authors", indexes = @Index(columnList = "last_name"))
public class Author {
    // ...
}
  • 說明: 在上例中,indexes 屬性指定了在 "authors" 表上創(chuàng)建一個索引,該索引包含一個名為 "last_name" 的列。
  1. *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

  1. 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" 列。
  1. **nullable**** 屬性:**
  • 作用: 指定列是否允許為null。
  • 示例:
@Entity
public class Author {
    @Column(nullable = false)
    private String fullName;
    // ...
}
  • 說明: 在上例中,@Column(nullable = false) 表示 fullName 列不允許為null。
  1. unique 屬性:
  • 作用: 指定列的值是否唯一。
  • 示例:
@Entity
public class Author {
    @Column(unique = true)
    private String email;
    // ...
}
  • 說明: 在上例中,@Column(unique = true) 表示 email 列的值必須是唯一的。
  1. length屬性:
  • 作用: 指定列的長度。
  • 示例:
@Entity
public class Author {
    @Column(length = 50)
    private String fullName;
    // ...
}
  • 說明: 在上例中,@Column(length = 50) 表示 fullName 列的長度為50。
  1. precisionscale 屬性:
  • 作用: 用于指定精度和小數(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。
  1. **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

  1. 基本使用:
@Entity
public class Author {
    @Id
    private Long id;
    // ...
}

在上例中,@Id 注解標(biāo)識了 Author 實(shí)體類的 id 字段作為主鍵。

  1. 生成策略 (**@GeneratedValue**):
@Entity
public class Author {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    // ...
}

通常與 @GeneratedValue 注解一起使用,用于指定主鍵的生成策略。GenerationType.IDENTITY 表示使用數(shù)據(jù)庫的自增長策略。

  1. 復(fù)合主鍵(Composite Primary Key):
@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Id
    private String isbn;
    // ...
}

在一些情況下,實(shí)體的主鍵可能由多個字段組成,這時可以在多個字段上都使用 @Id 注解,表示復(fù)合主鍵。

  1. 主鍵的類型:
@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    // ...
}

主鍵可以是任意 Java 數(shù)據(jù)類型,例如 Long、String、int 等。通常,主鍵類型應(yīng)該是可序列化的,并且不可變。

  1. 自定義主鍵生成器:
@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í)體。

  1. 基本使用:
@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"。

  1. **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í)體。

  1. **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í)體。

  1. **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。

  1. **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ù)庫中刪除。

  1. **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í)體。

  1. 基本使用:
@Entity
public class Book {
    @ManyToOne
    @JoinColumn(name = "author_id")
    private Author author;
    // ...
}

在上例中,@ManyToOne 注解表示 Book 實(shí)體類屬于一個 Author 實(shí)體。@JoinColumn 注解用于指定關(guān)聯(lián)的外鍵列名為 "author_id"。

  1. **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í)體。

  1. **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í)體。

  1. **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。

  1. **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í)體。

  1. **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_idcourse_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í)體的一部分。

  1. 標(biāo)識為可嵌入對象:
  • 使用 @Embeddable 注解標(biāo)識一個類,表示該類的實(shí)例可以被嵌入到其他實(shí)體中。
@Embeddable
public class Address {
    @Column(name = "street")
    private String street;

    @Column(name = "city")
    private String city;
}
  1. 嵌入對象的屬性:
  • @Embeddable 標(biāo)識的類中,定義需要嵌入的屬性,可以使用 @Column 注解進(jìn)行屬性的詳細(xì)配置。
  1. 嵌入到實(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;
}
  1. 嵌入對象的屬性在實(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ù)庫。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容