1. 程式人生 > 其它 >【SpringData&JPA從入門到精通】01-JPA 註解

【SpringData&JPA從入門到精通】01-JPA 註解

筆記來源:尚矽谷jpa開發教程全套完整版(初學者零基礎入門)

目錄

JPA 註解

基本註解

JPA 基本註解有 6 個:

  • @Entity
  • @Table
  • @Id
  • @GeneratedValue
  • @Column
  • @Basic

除此之外,還有 @Transient@Temporal 等註解

1、@Entity

@Entity 標註用於實體類宣告語句之前,指出該 Java 類為實體類,將對映到指定的資料庫表

如宣告一個實體類 Customer,它將對映到資料庫中的 customer 表上

@Entity
public class Customer

測試結果

Hibernate: 
    insert 
    into
        Customer
        (age, email, LAST_NAME) 
    values
        (?, ?, ?)

可以發現,加了 @Entity 註解之後,Customer 變成了一個實體類,具備了與資料表的對映關係;只不過表名和類名是一樣的

2、@Table

實體類與其對映的資料庫表不同名時,需要使用 @Table 標註說明。該標註與 @Entity

標註並列使用,置於實體類宣告語句之前,可寫於單獨語句行,也可與宣告語句同行

@Table 標註的常用選項是 name,用於指明資料庫的表名

@Table 標註還有幾個選項:

  • catalogschema,用於設定表所屬的資料庫目錄或模式,通常為資料庫名
  • uniqueConstraints 選項用於設定約束條件,通常不須設定
@Table(name = "JPA_CUSTOMERS")
@Entity
public class Customer

測試結果

Hibernate: 
    insert 
    into
        JPA_CUSTOMERS
        (age, email, LAST_NAME) 
    values
        (?, ?, ?)

3、@Id

@Id 標註用於宣告一個實體類的屬性對映為資料庫的主鍵列。該屬性通常置於屬性宣告語句之前,可與宣告語句同行,也可寫在單獨行上

@Id 標註也可置於屬性的 Getter 方法之前

@Id
public Integer getId() {
    return id;
}

4、@GeneratedValue

@GeneratedValue 用於標註主鍵的生成策略,通過 strategy 屬性指定

預設情況下,JPA 自動選擇一個最適合底層資料庫的主鍵生成策略:

  • SQLServer 對應 identity
  • MySQL 對應 auto increment

javax.persistence.GenerationType 中定義了以下幾種可供選擇的策略:

  • IDENTITY:採用資料庫 ID 自增長的方式來自增主鍵欄位,Oracle 不支援這種方式
  • AUTOJPA 自動選擇合適的策略,是預設選項
  • SEQUENCE:通過序列產生主鍵,通過 @SequenceGenerator 註解指定序列名,MySQL 不支援這種方式
  • TABLE:通過表產生主鍵,框架藉由表模擬序列產生主鍵,使用該策略可以使應用更易於資料庫移植
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
public Integer getId() {
    return id;
}

5、@Basic

@Basic 表示一個簡單屬性到資料庫表字段的對映,對於沒有任何標註的 getXxx() 方法,預設即為 @Basic

  • fetch:表示該屬性的讀取策略,有 EAGERLAZY 兩種,分別表示主支抓取和延遲載入,預設為 EAGER
  • optional:表示該屬性是否允許為 null,預設為 true
@Basic
public String getEmail() {
    return email;
}

6、@Column

實體的屬性與其對映的資料庫表的列不同名時需要使用,@Column 標註通常置於實體的屬性宣告語句之前,還可與 @Id 標註一起使用

@Column 標註的常用屬性是 name,用於設定對映資料庫表的列名。此外,該標註還包含其它多個屬性,如:uniquenullablelength

@Column 標註的 columnDefinition 屬性表示該欄位在資料庫中的實際型別

  • 通常 ORM 框架可以根據屬性型別自動判斷資料庫中欄位的型別,但是對於 Date 型別仍無法確定資料庫中欄位型別究竟是 DATETIME 還是 TIMESTAMP
  • 此外,String 的預設對映型別為 VARCHAR,如果要將 String 型別對映到特定資料庫的 BLOBTEXT 欄位型別

@Column 標註也可置於屬性的 Getter 方法之前

@Column(name = "LAST_NAME", length = 50, nullable = false)
public String getLastName() {
    return lastName;
}

7、@Transient

表示該屬性並非是一個到資料庫表字段的對映,ORM 框架將忽略該屬性

如果一個屬性並非資料庫表的欄位對映,就務必將其標示為 @Transient,否則 ORM 框架預設其註解為 @Basic

// 工具方法,不需要對映為資料表的一列
@Transient
public String getInfo() {
    return "lastName: " + this.lastName + ", email: " + email;
}

8、@Temporal

在核心的 Java API 中並沒有定義 Date 型別的精度(temporal precision)

而在資料庫中,表示 Date 型別的資料有 DATETIMETIMESTAMP 三種精度(即單純的日期、時間或者兩者兼備)

在進行屬性對映時可使用 @Temporal 註解來調整精度

@Temporal(TemporalType.DATE)
public Date getBirthDay() {
    return birthDay;
}
@Temporal(TemporalType.TIMESTAMP)
public Date getCreateTime() {
    return createTime;
}

測試結果

Hibernate: 
    insert 
    into
        JPA_CUSTOMERS
        (age, birthDay, createTime, email, LAST_NAME) 
    values
        (?, ?, ?, ?, ?)

檢視資料表結構

查詢資料表資料

9、用 table 生成主鍵詳解

將當前主鍵的值單獨儲存到一個數據庫的表中,主鍵的值每次都是從指定的表中查詢來獲得

這種方法生成主鍵的策略可以適用於任何資料庫,不必擔心不同資料庫不相容造成的問題

1)準備工作

create table JPA_ID_GENERATOR
(
	ID int(10) auto_increment,
	PK_NAME varchar(50) not null,
	PK_VALUE int(10) not null,
	constraint JPA_ID_GENERATOR_pk
		primary key (ID)
);
INSERT INTO jpa.jpa_id_generator (ID, PK_NAME, PK_VALUE) VALUES (1, 'CUSTOMER_ID', 1);
INSERT INTO jpa.jpa_id_generator (ID, PK_NAME, PK_VALUE) VALUES (2, 'STUDENT_ID', 10);
INSERT INTO jpa.jpa_id_generator (ID, PK_NAME, PK_VALUE) VALUES (3, 'ORDER_ID', 100);

表結構

表資料

2)編寫註解,@TableGenerator@GeneratedValue 配合使用

@TableGenerator(
    name = "ID_GENERATOR",
    table = "JPA_ID_GENERATOR",
    pkColumnName = "PK_NAME",
    pkColumnValue = "CUSTOMER_ID",
    valueColumnName = "PK_VALUE",
    allocationSize = 100
)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ID_GENERATOR")
@Id
public Integer getId() {
    return id;
}

其中 pkColumnNamepkColumnValuevalueColumnName 之間的關係如下圖所示

@TableGenerator 註解中各個屬性詳解:

  • name:主鍵生成策略名,與 @GeneratedValue 註解中 generator 值對應
  • table:表生成策略所持久化的表名
  • pkColumnName:在持久化表中,主鍵生成策略所對應的鍵
  • pkColumnValue:在持久化表中,主鍵生成策略所對應的值
  • valueColumnName:在持久化表中,主鍵當前所生成的值
  • allocationSize:每次主鍵增加的大小

3)測試結果

後臺日誌資訊

Hibernate: 
    select
        PK_VALUE 
    from
        JPA_ID_GENERATOR 
    where
        PK_NAME = 'CUSTOMER_ID' for update
            
Hibernate: 
    update
        JPA_ID_GENERATOR 
    set
        PK_VALUE = ? 
    where
        PK_VALUE = ? 
        and PK_NAME = 'CUSTOMER_ID'
Hibernate: 
    insert 
    into
        JPA_CUSTOMERS
        (age, birthDay, createTime, email, LAST_NAME, id) 
    values
        (?, ?, ?, ?, ?, ?)

JPA_ID_GENERATOR 表資料

JPA_CUSTOMERS 表資料

總結

本節重點掌握:

  • 類註解 @Entity@Table 的作用
  • 主鍵註解 Id@GeneratedValue 的作用
  • 屬性註解 @Column 的作用
  • @Basic@Transient 註解的區別
  • @Temporal 註解的使用
  • @TableGenerator 註解的使用

附上導圖,僅供參考