SpringBoot 應用JPA中的一些知識點

1、ManyToOne、OneToMany註解中的cascade

【在一切開始之前,我要先告訴大家:慎用級聯關係,不要隨便給all權限操作。應該根據業務需求選擇所需的級聯關係。否則可能釀成大禍。切記】

  • CascadeType.PERSIST
    官方文檔的說明:Cascade persist operation
    看到網上很多博客對這一枚舉值的解釋是:級聯持久化(保存)操作(持久保存擁有方實體時,也會持久保存該實體的所有相關數據。)
    我的內心OS是:媽蛋。我也知道是級聯persist操作啊關鍵是怎麼操作啊。媽蛋。擁有方實體是個什麼玩意兒,該實體又是個什麼玩意兒。
    經過實踐檢驗,我的理解是:給當前設置的實體操作另一個實體的權限。這個理解可以推廣到每一個CascadeType。因此,其餘CascadeType枚舉值將不再一一詳細解釋。
    For example:
public class Student {
    @ManyToMany(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY)
    private Set<Course> courses = new HashSet<>();
    //其他代碼略。
}

可以看到,我們在上面的代碼中給了Student對Course進行級聯保存(cascade=CascadeType.PERSIST)的權限。此時,若Student實體持有的Course實體在數據庫中不存在時,保存該Student時,系統將自動在Course實體對應的數據庫中保存這條Course數據。而如果沒有這個權限,則無法保存該Course數據。

  • CascadeType.REMOVE
    Cascade remove operation,級聯刪除操作。
    刪除當前實體時,與它有映射關係的實體也會跟着被刪除。
  • CascadeType.MERGE
    Cascade merge operation,級聯更新(合併)操作。
    當Student中的數據改變,會相應地更新Course中的數據。
  • CascadeType.DETACH
    Cascade detach operation,級聯脫管/遊離操作。
    如果你要刪除一個實體,但是它有外鍵無法刪除,你就需要這個級聯權限了。它會撤銷所有相關的外鍵關聯。
  • CascadeType.REFRESH
    Cascade refresh operation,級聯刷新操作。
    假設場景 有一個訂單,訂單裏面關聯了許多商品,這個訂單可以被很多人操作,那麼這個時候A對此訂單和關聯的商品進行了修改,與此同時,B也進行了相同的操作,但是B先一步比A保存了數據,那麼當A保存數據的時候,就需要先刷新訂單信息及關聯的商品信息後,再將訂單及商品保存。(來自良心會痛的評論)
  • CascadeType.ALL
    Cascade all operations,清晰明確,擁有以上所有級聯操作權限。

@GeneratedValue註解中的strategy

  • TABLE:使用一個特定的數據庫表格來保存主鍵。

    使用一個特定的數據庫表格來保存主鍵,持久化引擎通過關係數據庫的一張特定的表格來生成主鍵,這種策略的好處就是不依賴於外部環境和數據庫的具體實現,在不同數據庫間可以很容易的進行移植,但由於其不能充分利用數據庫的特性,所以不會優先使用。該策略一般與另外一個註解一起使用@TableGenerator,@TableGenerator註解指定了生成主鍵的表(可以在實體類上指定也可以在主鍵字段或屬性上指定),然後JPA將會根據註解內容自動生成一張表作爲序列表(或使用現有的序列表)。如果不指定序列表,則會生成一張默認的序列表,表中的列名也是自動生成,數據庫上會生成一張名爲sequence的表(SEQ_NAME,SEQ_COUNT)。序列表一般只包含兩個字段:第一個字段是該生成策略的名稱,第二個字段是該關係表的最大序號,它會隨着數據的插入逐漸累加。

  • SEQUENCE:根據底層數據庫的序列來生成主鍵,條件是數據庫支持序列。

    在某些數據庫中,不支持主鍵自增長,比如Oracle,其提供了一種叫做"序列(sequence)"的機制生成主鍵。此時,GenerationType.SEQUENCE就可以作爲主鍵生成策略。該策略的不足之處正好與TABLE相反,由於只有部分數據庫(Oracle,PostgreSQL,DB2)支持序列對象,MYsql不支持序列,所以該策略一般不應用於其他數據庫。類似的,該策略一般與另外一個註解一起使用@SequenceGenerator,@SequenceGenerator註解指定了生成主鍵的序列.然後JPA會根據註解內容創建一個序列(或使用一個現有的序列)。如果不指定序列,則會自動生成一個序列SEQ_GEN_SEQUENCE。

  • IDENTITY:主鍵由數據庫自動生成(主要是自動增長型)

    此種主鍵生成策略就是通常所說的主鍵自增長,數據庫在插入數據時,會自動給主鍵賦值,比如MySQL可以在創建表時聲明"auto_increment" 來指定主鍵自增長。該策略在大部分數據庫中都提供了支持(指定方法或關鍵字可能不同),但還是有少數數據庫不支持,所以可移植性略差。使用自增長主鍵生成策略是只需要聲明strategy = GenerationType.IDENTITY即可。

  • AUTO:主鍵由程序控制。

    把主鍵生成策略交給持久化引擎(persistence engine),持久化引擎會根據數據庫在以上三種主鍵生成策略中選擇其中一種。此種主鍵生成策略比較常用,由於JPA默認的生成策略就是GenerationType.AUTO,所以使用此種策略時.可以顯式的指定@GeneratedValue(strategy = GenerationType.AUTO)也可以直接@GeneratedValue。

支持的Id策略 數據庫名稱
不支持GenerationType.SEQUENCE
GenerationType.AUTO
GenerationType.IDENTITY
GenerationType.TABLE
MySQL
GenerationType.SEQUENCE
GenerationType.AUTO
不支持GenerationType.IDENTITY
GenerationType.TABLE
Oracle
GenerationType.SEQUENCE
GenerationType.AUTO
GenerationType.IDENTITY
GenerationType.TABLE
都支持
postgreSQL
GenerationType.SEQUENCE
GenerationType.AUTO
GenerationType.IDENTITY
GenerationType.TABLE
都支持
kingbase
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章