碼農小汪-Hibernate學習8-hibernate關聯關系注解表示@OneToMany mappedBy @ManyToMany @JoinTable...

近期我也是有點郁悶,究竟是程序中處理關聯關系。還是直接使用外鍵處理關聯關系呢?這個的說法不一致!程序中處理這樣的關聯關系的話。自己去維護這樣的約束。這樣的非常樂觀的一種做法!或者是直接在數據庫中處理這樣的直接的外鍵關聯,悲觀的做法!剛剛看到個帖子。有的公司表中一個外鍵都沒得。直接在程序中處理這樣的關聯關系。假設在Hibernate中處理外鍵關系的話。我們首先得有個主表的對象吧,然后在創建外鍵。感覺有點啰嗦。為啥不直接操作呢!

我僅僅要曉得你這個Id是外鍵即可了。各有各的說法。我想你也在思考這個問題。

現實的世界中確實非常少有孤立純在的東西。大多都是兩者之間純在某種關系的。有單向關系 僅僅能通過老師訪問學生。或者學生訪問老師
或者雙向關系 兩個都能夠相互的訪問

單向關系
1-1
1-N
N-1
N-N
雙向關系
1-1
1-N
N-N

單向N_1關聯是最多的,多個人住同一個地址。我們僅僅須要從人這一端知道他的住址即可了,不是必需知道某個地址的用戶。

為了讓我們兩個持久化實體關聯。程序在N的一端添加持久化實體的一個屬性,該屬性指向引用1的那一端的關聯實體
對于N-1(不管是單向關聯還是雙向關聯),都僅僅須要在N的一端使用@ManyToONe修飾關聯實體的屬性
有以下的一些屬性,事實上之前我也說過的,非常easy忘記。沒事的時候自己看看

屬性說明
Cascade級聯操作策略CascadeType.ALL….
Fetch抓取關聯實體的策略,之前說過FechType.Lazy 延遲和馬上
targetEntity該屬性的關聯實體的類名,在默認情況下通過反射獲得類名

默認情況下我們的targetEntity無需指定這個屬性的。但在一些特殊的情況下,比如使用@OneToMany.@ManyToMany 修飾 1-N N-N關聯的時候。關聯實體集合不帶泛型信息就必須指定了

無連接的N-1

無連接也就是不須要第三張表,維護我們的關聯關系。對于N_1關聯關系,我們僅僅須要在N的一端添加一列外鍵即可。

讓外鍵的值記錄到該屬性的實體即可。

Hibernate使用@JoinColumn來修飾代表關聯實體的屬性,用于映射底層的外鍵列。

這樣的就不使用連接表了

好啦,我們看一下樣例

多個人相應同一個地址

@Entity
@Table(name="person_inf")
public class Person
{@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定義該Person實體關聯的Address實體@ManyToOne(targetEntity=Address.class)// 映射外鍵列,指定外鍵列的列名為address_id、不同意為空@JoinColumn(name="address_id" , nullable=false)@Cascade(CascadeType.ALL)private Address address;........
}Address 里面非常正常就一個Id。和地址具體

他們建立的表什么樣子呢?
person_inf
person_id age name address_id
address_inf
address_id addressDetail

怎樣操作對象呢,由于address_id 是一個外鍵。

假設我們保存一個Person對象在我們的表中的話。我們應該首先有一個Address 對象吧。

能夠是存在數據庫中的。也能夠才瞬態對象。我們在插入的時候級聯操作。會先插入address_inf這個表中,然后才干夠使用外接啦。不然會報錯的,由于沒有存在的外鍵,肯定不行啦~

Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();// 創建一個Person對象Person p = new Person();// 創建一個瞬態的Address對象Address a = new Address("廣州天河");          p.setName("Test");p.setAge(21);// 設置Person和Address之間的關聯關系p.setAddress(a);// 持久化Person對象session.persist(p);//級聯的插入操作哦~。地址一定先于person插入數據表中,這里必須設置級聯操作,不然要報錯// 創建一個瞬態的Address對象Address a2 = new Address("上海虹口");        // 改動持久化狀態的Person對象p.setAddress(a2);                            tx.commit();HibernateUtil.closeSession();

有連接的N-1

我們的關聯關系的維護讓第三張表來維護啦。

對于大部分的N_1單向關系,僅僅要基于外鍵的關聯關系維護已經夠了。
假設有須要使用連接表來維護關聯關系,程序能夠使用連接表顯示的維護這樣的關系,所謂連接表就是建立第三張表格來維護我們的關系即可了。使用@JoinTable

以下的是java給的樣例,除了這些屬性外,我們還能夠指定targetEntity。指定關聯的實體是哪個!

也就是生成表的是哪個表所相應的實體。

 @JoinTable(name="CUST_PHONE",//相對于當前實體的外鍵,的列名。

參照的列名,也就是數據表中的名字 joinColumns= @JoinColumn(name="CUST_ID", referencedColumnName="ID"), //這個也是個外鍵,僅僅是不說當前實體里面的屬性。 inverseJoinColumns= @JoinColumn(name="PHONE_ID", referencedColumnName="ID") )

我們來看個樣例就知道啦

@Entity
@Table(name="person_inf")
public class Person
{// 標識屬性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定義該Person實體關聯的Address實體@ManyToOne(targetEntity=Address.class)// 顯式使用@JoinTable映射連接表@JoinTable(name="person_address", // 指定連接表的表名為person_address// 指定連接表中person_id外鍵列,參照到當前實體相應表的主鍵列joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id", unique=true),// 指定連接表中address_id外鍵列,參照到當前實體的關聯實體相應表的主鍵列inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id"))private Address address;
.....
@Entity
@Table(name="address_inf")
public class Address
{// 標識屬性@Id @Column(name="address_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private int addressId;// 定義地址具體信息的成員變量private String addressDetail;
}

這里產生的表的話,曾經的person的表不會改變address也不會變
僅僅是添加一個外表
person_address ——table
address_id person_id
使用連接表維護關系

單向1-1關聯

看上去 1-1 和N-1 幾乎相同啊,都須要在持久化實體中添加代表關聯實體的成員變量,從代碼上看沒得什么差別。由于N的一端和1的一端都能夠直接的訪問關聯的實體,。
不管單向的還是雙向的1-1關聯,都須要使用@OneToOne修飾關聯實體的屬性
有以下的
級聯操作,抓取屬性。optional 關聯關系是否可選。目標關聯實體的類名targetEntity.還有個重要的
mappedBy:該屬性合法的屬性值為關聯實體的屬性名該屬性指定關聯實體中的哪個屬性可引用當前的實體

樣例:基于外鍵的單向 1-1 關聯,無連接表

@Entity
@Table(name="person_inf")
public class Person
{// 標識屬性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定義該Person實體關聯的Address實體@OneToOne(targetEntity=Address.class)// 映射名為address_id的外鍵列,參照關聯實體相應表的addres_id主鍵列@JoinColumn(name="address_id", referencedColumnName="address_id" , unique=true)private Address address;地址肯定是獨一無二的嘛,對不正確!添加unique約束~.....
}

有連接表的也是幾乎相同,理解啦買即可了

@Entity
@Table(name="person_inf")
public class Person
{// 標識屬性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定義該Person實體關聯的Address實體@OneToOne(targetEntity=Address.class)@JoinTable(name="person_address",joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id" , unique=true),inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id", unique=true))private Address address;......
}

上面的東西,我相信僅僅要第一個看懂了即可了,跟著畫樣子澀。1-1嘛。肯定不能一樣的澀。

單向的1-N

1的一端要訪問N的一端。肯定的加個集合澀和前面的集合非常類似,可是如今的集合里的元素是關聯的實體啦。對于單向的1—N關聯關系。

僅僅須要在1的一端加入set類型的成員變量,記錄全部的關聯的實體。

即可了。具體怎么操作,我們慢慢的說來。

一個個字的打還是能夠的。添加自己的理解
@OneToMany
級聯。抓取,目標實體,mappedBy

無連接表的單向1-N

1個人有多個住處~~~貪官!

不然怎么買的起這么多房子,如今的房價你又不是不知道。哼~

@Entity
@Table(name="person_inf")
public class Person
{@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定義該Person實體全部關聯的Address實體,沒有指定cascade屬性@OneToMany(targetEntity=Address.class)// 映射外鍵列。此處映射的外鍵列將會加入到關聯實體相應的數據表中。為啥呢?@JoinColumn(name="person_id" , referencedColumnName="person_id")private Set<Address> addresses= new HashSet<>();........}

這里的外鍵列不會添加到當前實體相應的數據表中,而是添加到,關聯實體Address相應的數據表中,有點特殊!

為什么。之前我們使用set集合的時候都必須在添加一個表記得?僅僅只是這里添加到了關聯實體里面去了。

而不是在添加一張表~~

N的端不維護關系,沒得變化~

有連接的1-N

@Entity
@Table(name="person_inf")
public class Person
{// 標識屬性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定義該Person實體全部關聯的Address實體@OneToMany(targetEntity=Address.class)// 映射連接表為person_address@JoinTable(name="person_address",// 定義連接表中名為person_id的外鍵列。該外鍵列參照當前實體相應表的主鍵列joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id"),// 定義連接表中名為address_id的外鍵列。// 該外鍵列參照當前實體的關聯實體相應表的主鍵列inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id", unique=true))private Set<Address> addresses= new HashSet<>();
...
}

這里是1對N 1個人有多個住的地方,可是每一個都是不一樣的,所以要添加unique約束
由于採用連接表了,我們的Person表中沒有存在維護連接關系,能夠隨意的持久化操作。


1個person 2個adress 要插入5次操作哦
自己想想為什么?

單向的N-N也是須要的

@ManyToMany
N-N關系必須須要連接表啦,和有連接的1-N類似,可是要把unique約束去掉啦~
直接改動啦,上面那個~

@Entity
@Table(name="person_inf")
public class Person
{// 標識屬性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定義該Person實體全部關聯的Address實體@ManyToMany(targetEntity=Address.class)// 映射連接表為person_address@JoinTable(name="person_address",// 定義連接表中名為person_id的外鍵列,該外鍵列參照當前實體相應表的主鍵列joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id"),// 定義連接表中名為address_id的外鍵列,// 該外鍵列參照當前實體的關聯實體相應表的主鍵列inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id"))private Set<Address> addresses= new HashSet<>();
...
}

轉載于:https://www.cnblogs.com/wzzkaifa/p/7354159.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282745.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282745.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282745.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HTML中彈窗中加入圖片,javascript里怎么實現點擊圖片彈出對話框?

JavaScript中可以使用document.getElementsByTagName方法后去img標簽&#xff0c;然后遍歷所有img標簽并為其添加點擊事件實現點擊彈出對話框。JavaScript實現點擊圖片彈出對話框&#xff1a;img {width: 500px;height: 300px;}//獲取所有的img標簽var imgObjs document.getEl…

Java學習優秀網站

各類程序員學習路線圖&#xff1a; http://www.runoob.com/coder-learn-path 博學谷&#xff1a; http://v.itcast.cn/map/22.html 慕課網&#xff1a; http://www.imooc.com/course/programdetail/pid/31 轉載于:https://www.cnblogs.com/Arsene/p/6441831.html

Dcloud課程2 什么是Dcloud

Dcloud課程2 什么是Dcloud 一、總結 一句話總結&#xff1a;DCloud提供了一套快速開發應用的跨平臺技術方案。 1、DCloud的產品架構&#xff1f; MUI(H5)HBuilder 2、什么是MUI&#xff1f; 最接近原生體驗的移動App的UI框架。 3、什么是H5&#xff1f; html5功能增強標準 二、…

html5 輪詢自動刷新數據,后臺調用exe,前端定時輪詢調用結果

前提使用asp.net core 2.1前端使用vueui使用element-ui前端發送請求用Axios新建asp.net core程序1.jpg修改Index.html{Layout null;}test{{ msg }}發送請求打開記事本// 創建 Vue 實例&#xff0c;得到 ViewModelvar vm new Vue({el: #app,data: {msg: 準備發送請求打開exe},…

洛谷 P2951 [USACO09OPEN]捉迷藏Hide and Seek

題目描述 Bessie is playing hide and seek (a game in which a number of players hide and a single player (the seeker) attempts to find them after which various penalties and rewards are assessed; much fun usually ensues). She is trying to figure out in which…

使用ssh免密碼登錄Linux服務器

頻繁登錄Linux服務器時&#xff0c;使用ssh <username><host>的方式登錄&#xff0c;但是每次都需要輸入密碼是件很麻煩的事。我們還可以使用私鑰/公鑰對的方式在免密碼登錄服務器。首先需要在遠程服務器中安裝ssh-server服務&#xff0c;才可以使用ssh登錄。如果沒…

linux下tomcat開啟遠程調試

1.center下&#xff0c;在startup.sh文件首行中添加如下語句 declare -x CATALINA_OPTS"-server -Xdebug -Xnoagent -Djava.compilerNONE -Xrunjdwp:transportdt_socket,servery,suspendn,address8000"(不要換行&#xff0c;要在同一行)Ubuntu下&#xff0c;在catali…

.NET 7 RC1 發布

原文鏈接&#xff1a;https://devblogs.microsoft.com/dotnet/announcing-dotnet-7-rc-1/[1]原文作者&#xff1a;Jeremy Likness&#xff0c;Angelos Petropoulos&#xff0c;Jon Douglas翻譯&#xff1a;沙漠盡頭的狼(谷歌翻譯加持)今天我們宣布 .NET 7 候選版本 1。這是生產…

html 字符串最后加空格,html space空格符

htmlcss 代碼在網頁中如何插入打出空格字符實現方法**摘要瀏覽器總是會截短 HTML 頁面中的空格。HTML將所有空格字符&#xff0c;制表符&#xff0c;空格和回車符壓縮為一個字符。如果要縮進段落&#xff0c;則不能簡單地鍵入五個空格然后開始文本。 如果您在文本中寫 10 個空格…

.NET MAUI實戰 FilePicker

1.概要最近在遷移 GeneralUpdate.Tool的時候需要用到文件選擇&#xff0c;在MAUI中可以使用FilePicker進行選擇。ref1: https://gitee.com/Juster-zhu/GeneralUpdateref2:https://docs.microsoft.com/zh-cn/dotnet/maui/platform-integration/storage/file-picker?tabswindows…

SQL Server中,with as使用介紹

一&#xff0e;WITH AS的含義 WITH AS短語&#xff0c;也叫做子查詢部分&#xff08;subquery factoring&#xff09;&#xff0c;可以讓你做很多事情&#xff0c;定義一個SQL片斷&#xff0c;該SQL片斷會被整個SQL語句所用到。有的時候&#xff0c;是為了讓SQL語句的可讀…

從新手機到老股票 閑魚為何會淪為騙子與營銷的新平臺?

國內電商一直空缺一個有規模的綜合二手交易平臺。閑魚的出現&#xff0c;有一定程度上滿足了喜歡淘二手、喜歡“撿漏”的用戶需求。雖加入了擔保和第三方支付等環節&#xff0c;但這種隨機的二手交易行為不可避免地會出現上當、受騙的情況出現。本質上來說&#xff0c;閑魚仍然…

網上書店模板asp與html,一個簡單的網上書城的例子(三)_asp實例

buy.asp:顯示商品和用戶購物&#xff01;DbPath SERVER.MapPath("ShopBag.mdb")Set conn Server.CreateObject("ADODB.Connection")conn.open "driver{Microsoft Access Driver (*.mdb)};dbq" & DbPathCategoryIDRequest("CategoryID…

使用C#編寫一個.NET分析器(一)

譯者注這是在Datadog公司任職的Kevin Gosse大佬使用C#編寫.NET分析器的系列文章之一&#xff0c;在國內只有很少很少的人了解和研究.NET分析器&#xff0c;它常被用于APM&#xff08;應用性能診斷&#xff09;、IDE、診斷工具中&#xff0c;比如Datadog的APM&#xff0c;Visual…

內置數據類型

Java語言提供了八種基本類型。六種數字類型&#xff08;四個整數型&#xff0c;兩個浮點型&#xff09;&#xff0c;一種字符類型&#xff0c;還有一種布爾型。 byte&#xff1a; byte 數據類型是8位、有符號的&#xff0c;以二進制補碼表示的整數&#xff1b; 最小值是 -128&…

算法學習之循環結構程序設計

for循環 打印1,2,3&#xff0c;...&#xff0c;n每個占一行。 #include <conio.h> #include<stdio.h> int main(){int i,n;scanf("%d",&n);for(i1;i<n;i){printf("%d\n",i);}getch();return 0; } 分支結合循環&#xff0c;威力很強大 輸…

Linux常用命令 (分門別類)

一、系統安全: su: 用于切換當前用戶身份到其他用戶身份&#xff0c;變更時須輸入所要變更的用戶帳號與密碼 sudo: 用來以其他身份來執行命令&#xff0c;預設的身份為root lastlog: 用于顯示系統中所有用戶最近一次登錄信息 lastb: 用于顯示用戶錯誤的登錄列表&#x…

hibernate自定義校驗器使用(字段在in范圍之內)

2019獨角獸企業重金招聘Python工程師標準>>> 1.自定義注解類DigitsMustIn Constraint(validatedBy DigitsMustInValidator.class) //具體的實現 Target({java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.FIELD}) Retention(java.lang.a…

sql將html轉成excel,使用SQL*PLUS,構建完美excel或html輸出

通過SQL*PLUS我們可以構建友好的輸出&#xff0c;滿足多樣化用戶需求。本例通過簡單示例&#xff0c;介紹通過sql*plus輸出xls&#xff0c;html兩種格式文件.首先創建兩個腳本:1.main.sql用以設置環境&#xff0c;調用具體功能腳本2.功能腳本-get_tables.sql為實現具體功能之腳…

[cogs347]地震

COGS&#xff1a;地震&#xff08;平衡樹&#xff09; COGS上一道題。。。文件名是equake 還是又打了一遍板子。。。 加個lazy標記就行了。。。 注意查詢時先下傳標記&#xff08;lazy&#xff09; // It is made by XZZ #include<cstdio> #include<algorithm> #de…