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 不支援這種方式。
- AUTO: JPA 自動選擇合適的策略,是預設選項。
- 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: 級聯操作策略
- CascadeType.ALL 級聯所有操作
- CascadeType.PERSIST 級聯新增
- CascadeType.MERGE 級聯歸併更新
- CascadeType.REMOVE 級聯刪除
- CascadeType.REFRESH 級聯重新整理
- CascadeType.DETACH 級聯分離
- fetch: fetch 表示該屬性的載入讀取策略 (預設值為
EAGER
)
- EAGER 主動抓取
- 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: 級聯操作策略
- CascadeType.ALL 級聯所有操作
- CascadeType.PERSIST 級聯新增
- CascadeType.MERGE 級聯歸併更新
- CascadeType.REMOVE 級聯刪除
- CascadeType.REFRESH 級聯重新整理
- CascadeType.DETACH 級聯分離
- fetch: fetch 表示該屬性的載入讀取策略(@ManyToOne 的預設值是
EAGER
,@OneToMany 的預設值是LAZY
)
- EAGER 主動抓取
- 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: 級聯操作策略
- CascadeType.ALL 級聯所有操作
- CascadeType.PERSIST 級聯新增
- CascadeType.MERGE 級聯歸併更新
- CascadeType.REMOVE 級聯刪除
- CascadeType.REFRESH 級聯重新整理
- CascadeType.DETACH 級聯分離
- fetch: fetch 表示該屬性的載入讀取策略 (預設值為
LAZY
)
- EAGER 主動抓取
- LAZY 延遲載入,只有用到該屬性時才會去載入
- mappedBy: 指定關聯關係,該引數只用於關聯關係被擁有方
只用於雙向關聯@OneToOne
,@OneToMany
,@ManyToMany
。而@ManyToOne
中沒有。
@ManyToMany(mappedBy = “xxx”)
表示xxx所對應的類為關係被擁有方,而關聯的另一方為關係擁有方: - 關係擁有方:對應擁有外來鍵的資料庫表
- 關係被擁有方:對應主鍵被子表引用為外來鍵的資料庫表
- mappedBy: 指定關聯關係,該引數只用於關聯關係被擁有方
//單向 多對多
@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;
有錯誤歡迎指出^_^