spring jpa ManyToMany原理及用法詳解
1.java和jpa 中所有的關(guān)系都是單向的。這個關(guān)系數(shù)據(jù)庫不同,關(guān)系數(shù)據(jù)庫,通過外鍵定義并查詢,使得反向查詢總是存在的。
2.JPA還定義了一個OneToMany關(guān)系,它與ManyToMany關(guān)系類似,但反向關(guān)系(如果已定義)是ManyToOne關(guān)系。
OneToMany與JPA中ManyToMany關(guān)系的主要區(qū)別在于,ManyToMany總是使用中間關(guān)系連接表來存儲關(guān)系,
OneToMany可以使用連接表或者目標(biāo)對象的表引用中的外鍵源對象表的主鍵。
@OneToMany(cascade = CascadeType.ALL) @JoinColumn(name = "OPR_WARE_SYSCONFIG_ID",foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) private List<WarehouseVO> warehouse;
wareHouseVO的表通過外鍵字段關(guān)聯(lián),而定義了OneToMany的屬性的VO則不需要添加表字段。
ManyToOne:
@ManyToOne @JoinColumn(name = "OPR_WAREHOUSE_ENV_ID") private EnvironmentVO env ;
總結(jié),作為many的一方需要有外鍵關(guān)聯(lián)One的一方。
@ManyToMany 注解
manyToMany需要和@JoinTable表結(jié)合使用,ManyToMany總是使用中間關(guān)系連接表來存儲關(guān)系。如果兩個Vo都定義了ManyToMany的話,因為單向關(guān)系,會生成有2個中間表。所以需要改造成雙向關(guān)系,使其只存在一個中間表。
例子:
a:一方不需要mappedBy屬性,一方需要。
@ManyToMany @JoinTable(name = "AUTO_SYSTEM", joinColumns = { @JoinColumn(name = "OPR_AUTO_ID") }, inverseJoinColumns = { @JoinColumn(name = "OPR_SYSTEM_ID") }, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT), inverseForeignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) private List<SystemVO> systems; @ManyToMany(mappedBy = "students") private List<Service> services;
b:
@Entity public class Student { @Id private String id; @ManyToMany @JoinTable private List<Teacher> teachers; } @Entity public class Teacher { @Id private String id; @ManyToMany @JoinTable private List<Student> students; }
@ManyToMany即表示了老師和學(xué)生的多對多關(guān)系。@ManyToMany注解可以用在字段或方法上
但是這樣會有兩個表出現(xiàn),TEACHER_STUDENTS表和STUDENT_TEACHERS。
原因是這里的多對多關(guān)系正是維基百科提到的單向原則。老師和學(xué)生雖然分別定義了自己的多對多關(guān)系,但這個關(guān)系都是單向的,要使關(guān)系成為雙向。
mappedBy 屬性
mappedBy是OneToOne、OneToMany和ManyToMany這三種關(guān)聯(lián)關(guān)系的屬性。
用來標(biāo)注擁有這種關(guān)系的字段。 除非關(guān)系是單向的,否則是必需的。
什么叫擁有關(guān)聯(lián)關(guān)系呢,假設(shè)是雙向一對一的話,那么擁有關(guān)系的這一方有建立、解除和更新與另一方關(guān)系的能力。而另一方?jīng)]有,只能被動管理。
由于JoinTable和JoinColumn一般定義在擁有關(guān)系的這一端,而mappedBy一定是定義在關(guān)系的被擁有方(the owned side),也就是跟定義JoinTable
和JoinColumn互斥的一方,它的值指向擁有方中關(guān)于被擁有方的字段,可能是一個對象(OneToMany),也可能是一個對象集合(ManyToMany)。
@Entity public class Student { @Id private String id; @ManyToMany(mappedBy = "students") private List<Teacher> teachers; } @Entity public class Teacher { @Id private String id; @ManyToMany @JoinTable(“student”) private List<Student> students; }
這時中間表只有一張TEACHER_STUDENTS,關(guān)聯(lián)關(guān)系也變成了我們想要的雙向關(guān)系。
Cascade 級聯(lián)關(guān)系
實際業(yè)務(wù)中,我們通常會遇到以下情況:
1.用戶和用戶的收貨地址是一對多關(guān)系,當(dāng)用戶被刪除時,這個用戶的所有收貨地址也應(yīng)該一并刪除。
2.訂單和訂單中的商品也是一對多關(guān)系,但訂單被刪除時,訂單所關(guān)聯(lián)的商品肯定不能被刪除。
此時只要配置正確的級聯(lián)關(guān)系,就能達(dá)到想要的效果。
級聯(lián)關(guān)系類型:
- CascadeType.REFRESH:級聯(lián)刷新,當(dāng)多個用戶同時作操作一個實體,為了用戶取到的數(shù)據(jù)是實時的,在用實體中的數(shù)據(jù)之前就可以調(diào)用一下refresh()方法
- CascadeType.REMOVE:級聯(lián)刪除,當(dāng)調(diào)用remove()方法刪除Order實體時會先級聯(lián)刪除OrderItem的相關(guān)數(shù)據(jù)
- CascadeType.MERGE:級聯(lián)更新,當(dāng)調(diào)用了Merge()方法,如果Order中的數(shù)據(jù)改變了會相應(yīng)的更新OrderItem中的數(shù)據(jù)
- CascadeType.ALL:包含以上所有級聯(lián)屬性
- CascadeType.PERSIST:級聯(lián)保存,當(dāng)調(diào)用了Persist() 方法,會級聯(lián)保存相應(yīng)的數(shù)據(jù)
需要注意的是,CascadeType.ALL要謹(jǐn)慎使用,為了達(dá)到數(shù)據(jù)同步,很多人喜歡用CascadeType.ALL來實現(xiàn)。但上面訂單和商品的例子就不適用。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java中為什么重寫equals()也需要重寫hashCode方法
這篇文章主要介紹了Java中為什么重寫equals()也需要重寫hashCode(),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04java組件commons-fileupload實現(xiàn)文件上傳
這篇文章主要介紹了java借助commons-fileupload組件實現(xiàn)文件上傳,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-10-10SpringBoot使用Feign進行服務(wù)間通信的實現(xiàn)示例代碼
Feign是一個開源的Java HTTP客戶端,可以幫助我們在SpringBoot應(yīng)用中快速構(gòu)建和使用HTTP客戶端,方便實現(xiàn)服務(wù)間的通信,本文就來介紹一下SpringBoot使用Feign進行服務(wù)間通信的實現(xiàn)示例代碼,感興趣的可以了解一下2024-01-01Mybatis輸入輸出映射及動態(tài)SQL Review
這篇文章主要介紹了Mybatis輸入輸出映射及動態(tài)SQL Review,需要的朋友可以參考下2017-02-02SpringBoot3集成ElasticSearch的方法詳解
Elasticsearch是一個分布式、RESTful風(fēng)格的搜索和數(shù)據(jù)分析引擎,適用于各種數(shù)據(jù)類型,數(shù)字、文本、地理位置、結(jié)構(gòu)化數(shù)據(jù)、非結(jié)構(gòu)化數(shù)據(jù),本文給大家詳解介紹了SpringBoot3集成ElasticSearch的方法,需要的朋友可以參考下2023-08-08Java實現(xiàn)局域網(wǎng)聊天室功能(私聊、群聊)
這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)局域網(wǎng)聊天室功能,包括私聊、群聊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05