1. 程式人生 > >Jpa 實體類常用註解

Jpa 實體類常用註解

記錄一些spring-data-jpa常用的註解,程式碼執行環境:spring boot + spring-data-jpa

1. @Entity

被Entity標註的實體類將會被JPA管理控制,在程式執行時,JPA會識別並對映到指定的資料庫表
唯一引數name:指定實體類名稱,預設為當前實體類的非限定名稱。
若給了name屬性值即@Entity(name="XXX"),則jpa在倉儲層(資料層)進行自定義查詢時,所查的表名應是XXX。
如:select s from XXX s

2. @Table

當你想生成的資料庫表名與實體類名稱不同時,使用 @Table(name="資料庫表名"
),與@Entity標註並列使用,置於實體 類宣告語句之前 @Entity @Table(name="t_student") public class student{ ... }

@Table中的引數(不常用)

  • catalog: 用於設定表所對映到的資料庫的目錄
  • schema: 用於設定表所對映到的資料庫的模式
  • uniqueConstraints: 設定約束條件

3. @Id

@Id 用於實體類的一個屬性或者屬性對應的getter方法的標註,被標註的的屬性將對映為資料庫主鍵

4. @GeneratedValue

與@Id一同使用,用於標註主鍵的生成策略,通過 strategy 屬性指定。預設是JPA自動選擇合適的策略
在 javax.persistence.GenerationType 中定義了以下幾種可供選擇的策略:
 - IDENTITY
:採用資料庫ID自增長的方式產生主鍵,Oracle 不支援這種方式。
- AUTOJPA 自動選擇合適的策略,是預設選項。 - SEQUENCE:通過序列產生主鍵,通過@SequenceGenerator標註指定序列名,MySQL 不支援這種方式。 - TABLE:通過表產生主鍵,框架藉由表模擬序列產生主鍵,使用該策略更易於做資料庫移植。

5. @Basic

@Basic表示一個簡單的屬性到資料庫表的欄位的對映,對於沒有任何標註的 getXxxx() 方法,預設即為@Basic(fetch=FetechType.EAGER)
@Basic引數:
  1. fetch 表示該屬性的載入讀取策略
    1.1
EAGER 主動抓取 (預設為EAGER) 1.2 LAZY 延遲載入,只有用到該屬性時才會去載入 2. optional (預設為 true) 表示該屬性是否允許為null

6. @Column

通常置於實體的屬性宣告之前,可與 @Id 標註一起使用
@Column引數:
  1. name: 指定對映到資料庫中的欄位名
  2. unique: 是否唯一,預設為false
  3. nullable: 是否允許為null,預設為true
  5. insertable: 是否允許插入,預設為true
  6. updatetable: 是否允許更新,預設為true
  7. columnDefinition: 指定該屬性對映到資料庫中的實際型別,通常是自動判斷。

7. @Transient

JPA會忽略該屬性,不會對映到資料庫中,即程式執行後資料庫中將不會有該欄位

8. @Temporal

Java中沒有定義 Date 型別的精度,而資料庫中,表示時間型別的資料有 DATE,TIME,TIMESTAMP三種精度
  - @Temporal(TemporalType.DATE) 表示對映到資料庫中的時間型別為 DATE,只有日期
  - @Temporal(TemporalType.TIME) 表示對映到資料庫中的時間型別為 TIME,只有時間
  - @Temporal(TemporalType.TIMESTAMP) 表示對映到資料庫中的時間型別為 TIMESTAMP,日期和時間都有

9. @Embedded 和 @Embeddable

用於一個實體類要在多個不同的實體類中進行使用,而本身又不需要獨立生成一個數據庫表

網上有一份比較詳細說明,可參考連結

10. @JoinColumn

定義表關聯的外來鍵欄位名
常用引數有:
  1. name: 指定對映到資料庫中的外來鍵的欄位名
  2. unique: 是否唯一,預設為false
  3. nullable: 是否允許為null,預設為true
  4. insertable: 是否允許插入,預設為true
  5. updatetable: 是否允許更新,預設為true
  6. columnDefinition: 指定該屬性對映到資料庫中的實際型別,通常是自動判斷。

11. @OneToOne

引數:

  • targetEntity: 指定關聯實體型別,預設為被註解的屬性或方法所屬的類
  • cascade: 級聯操作策略
    1. CascadeType.ALL 級聯所有操作
    2. CascadeType.PERSIST 級聯新增
    3. CascadeType.MERGE 級聯歸併更新
    4. CascadeType.REMOVE 級聯刪除
    5. CascadeType.REFRESH 級聯重新整理
    6. CascadeType.DETACH 級聯分離
  • fetch: fetch 表示該屬性的載入讀取策略 (預設值為 EAGER)
    1. EAGER 主動抓取
    2. LAZY 延遲載入,只有用到該屬性時才會去載入
  • optional: 預設為true,關聯欄位是否為空
    如果為false,則常與@JoinColumn一起使用
  • mappedBy: 指定關聯關係,該引數只用於關聯關係被擁有方
    只用於雙向關聯@OneToOne,@OneToMany,@ManyToMany。而@ManyToOne中沒有
    @OneToOne(mappedBy = “xxx”)
    表示xxx所對應的類為關係被擁有方,而關聯的另一方為關係擁有方
    • 關係擁有方:對應擁有外來鍵的資料庫表
    • 關係被擁有方:對應主鍵被子表引用為外來鍵的資料庫表
  • orphanRemoval:預設值為false
    判斷是否自動刪除與關係擁有方不存在聯絡的關係被擁有方(關係被擁有方的一個主鍵在關係擁有方中未被引用,
    當jpa執行更新操作時,是否刪除資料庫中此主鍵所對應的一條記錄,若為true則刪除)
//單向 一對一
@Entity  
public class Emp{//員工
  @Id
  @GeneratedValue
  privte Integer eId;

  @Column(length = 40)
  private String empName;

  @OneToOne(cascade = CascadeType.ALL)
  private Identity identity;
  //get,set方法省略
}

@Entity
public class Identity{//身份證
  //...
}
//雙向 一對一
@Entity  
public class Emp{
  @Id
  @GeneratedValue
  privte Integer eId;

  @Column(length = 40)
  private String empName;

  @OneToOne(cascade = CascadeType.ALL)
  private Identity identity;
  //get,set方法省略
}

@Entity
public class Identity{
  @Id
  @GeneratedValue
  privte Integer iId;

  @OneToOne(cascade = CascadeType.ALL, mappedBy = "identity")
  private Emp emp;
  //...
}

以上例子,雙向一對一,Emp 為關係擁有方,Identity 為關係被擁有方。
執行spring-data-jpa新增操作時,如果通過Identity的資料訪問層進行新增操作(IdentityRepository.save())
,Emp表和Identity表都有資料,但是不會設定這兩條資料的關係,Emp表中的外來鍵為null。
反之,以關係擁有方Emp的資料訪問層進行新增操作(EmpRepository.save()),Emp表和Identity表都有資料,並且
設定了兩條資料的關係,即Emp表中的外來鍵也得到正確新增

12. @ManyToOne、@OneToMany

多對一(也可叫一對多,只是前後表顛倒一下而已),只有雙向多對一時才用得到@OneToMany。多對一中多的一方必定是對應資料庫中擁有外來鍵的表,即是關係擁有方,@ManyToOne只用在多對一中代表多的一類中,因為mappedBy只用於關係被擁有方,所以@ManyToOne引數中不包含mappedBy

@ManyToOne引數:

  • targetEntity: 指定關聯實體型別,預設為被註解的屬性或方法所屬的類
  • cascade: 級聯操作策略
    1. CascadeType.ALL 級聯所有操作
    2. CascadeType.PERSIST 級聯新增
    3. CascadeType.MERGE 級聯歸併更新
    4. CascadeType.REMOVE 級聯刪除
    5. CascadeType.REFRESH 級聯重新整理
    6. CascadeType.DETACH 級聯分離
  • fetch: fetch 表示該屬性的載入讀取策略(@ManyToOne 的預設值是 EAGER,@OneToMany 的預設值是 LAZY)
    1. EAGER 主動抓取
    2. LAZY 延遲載入,只有用到該屬性時才會去載入
  • optional: 預設為true,關聯欄位是否為空
    如果為false,則常與@JoinColumn一起使用

@OneToMany 引數除上述以外還有:

  • mappedBy: 指定關聯關係,該引數只用於關聯關係被擁有方
    只用於雙向關聯@OneToOne,@OneToMany,@ManyToMany。而@ManyToOne中沒有
    @OneToMany(mappedBy = “xxx”)
    表示xxx所對應的類為關係被擁有方,而關聯的另一方為關係擁有方

    • 關係擁有方:對應擁有外來鍵的資料庫表
    • 關係被擁有方:對應主鍵被子表引用為外來鍵的資料庫表
  • orphanRemoval:預設值為false
    判斷是否自動刪除與關係擁有方不存在聯絡的關係被擁有方(關係被擁有方的一個主鍵在關係擁有方中未被引用,
    當jpa執行更新操作時,是否刪除資料庫中此主鍵所對應的一條記錄,若為true則刪除)

//單向 多對一
@Entity
public class Emp{
  @Id
  @GeneratedValue
  privte Integer eId;

  @Column(length = 40)
  private String empName;

  @ManyToOne(cascade = CascadeType.ALL)
  private Dept dept;
  //...
}

@Entity
public class Dept{
  @Id
  @GeneratedValue
  privte Integer dId;

  @Column(length = 40)
  private String deptName;
  //...
}
//雙向 多對一
@Entity
public class Emp{
  @Id
  @GeneratedValue
  privte Integer eId;

  @Column(length = 40)
  private String empName;

  @ManyToOne(cascade = CascadeType.ALL)
  private Emp emp;
  //...
}

@Entity
public class Dept{
  @Id
  @GeneratedValue
  privte Integer dId;

  @Column(length = 40)
  private String deptName;

  @OneToMany(cascade = CascadeType.ALL, mappedBy = "emp")
  private List<Emp> emps;
  //...
}

無論雙向關聯還是單向關聯,資料庫中均會在Emp表中自動生成一個外來鍵(dept_d_id)

13. @ManyToMany

  • targetEntity: 指定關聯實體型別,預設為被註解的屬性或方法所屬的類
  • cascade: 級聯操作策略
    1. CascadeType.ALL 級聯所有操作
    2. CascadeType.PERSIST 級聯新增
    3. CascadeType.MERGE 級聯歸併更新
    4. CascadeType.REMOVE 級聯刪除
    5. CascadeType.REFRESH 級聯重新整理
    6. CascadeType.DETACH 級聯分離
  • fetch: fetch 表示該屬性的載入讀取策略 (預設值為 LAZY)
    1. EAGER 主動抓取
    2. LAZY 延遲載入,只有用到該屬性時才會去載入
      • mappedBy: 指定關聯關係,該引數只用於關聯關係被擁有方
        只用於雙向關聯@OneToOne,@OneToMany,@ManyToMany。而@ManyToOne中沒有。
        @ManyToMany(mappedBy = “xxx”)
        表示xxx所對應的類為關係被擁有方,而關聯的另一方為關係擁有方:
      • 關係擁有方:對應擁有外來鍵的資料庫表
      • 關係被擁有方:對應主鍵被子表引用為外來鍵的資料庫表
//單向 多對多
@Entity
public class Student{
  @ManyToMany(cascade = CascadeType.ALL)
  private List<Course> courses;
  //...
}

@Entity
public class Course{
  //...
}
//雙向 多對多
@Entity
public class Student{
  @ManyToMany(cascade = CascadeType.ALL)
  private List<Course> courses;
  //...
}

@Entity
public class Course{
  @ManyToMany(cascade = CascadeType.ALL, mappedBy = "courses")
  private List<Student> students;
  //...
}

所有雙向關聯使用時需謹慎,查詢時容易引起棧記憶體溢位,儘量使用單向關聯

14. @Enumerated

當實體類中有列舉型別的屬性時,預設情況下自動生成的資料庫表中對應的欄位型別是列舉的索引值,是數字型別的,若希望資料庫中儲存的是列舉對應的String型別,在屬性上加入@Enumerated(EnumType.STRING)註解即可。

@Enumerated(EnumType.STRING)
@Column(nullable = true)
private RoleEnum role;

有錯誤歡迎指出^_^