JPA 中 @JoinColumn 的 name 和 referencedColumnName 屬性怎麼辨別

一、@JoinColumn

@JoinColumn 的作用就是聲明關聯關係的,什麼是關聯關係?

就是我們在數據庫設計時常說的一對多、多對一、多對多關係。因此,@JoinColumn 必須和這些關係註解一起使用,否則是沒有意義的。

二、name 和 referencedColumnName

剛開始接觸這兩個屬性會覺得很難理解,特別是看書的時候總是分不清,看下面的例子:

// Address表對應的Entity
Class Address{
	@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long addressID;
    ...
}

// User表對應的Entity
Class User{
	...
	// 顯然下面這個屬性表示每個User對應一個Address,思考一下:
	// 平時我們在設計數據庫的時候會怎麼處理這種關係?我一般對這
	// 一對一的關係,都會直接在User表中添加一個字段指向Address
	// 的主鍵,而下面註解確實是這樣做的。
 	@OneToOne
    @JoinColumn(name = "addressID", referencedColumnName = "id")
    private Address address;
    ...
}

其實這兩個屬性指向的都是數據庫字段,也就是數據庫裏面真真實實存在的表的字段,而不是我們在Java程序中的成員變量名(重要)。

如上面的代碼,它表示在User表中添加一個addressID字段,這個字段的取值就是 Address 表的 id,也就是主鍵,也就說明了它通過這個字段關聯着兩張表(重要,重要,重要),這其實就是我們在學習數據庫時處理一對一關係的一種方法,是不是很熟悉?

所以,一定記住,兩個屬性都是指數據庫裏的字段!!!!

  • name:當前表的字段
  • referencedColumnName:引用表對應的字段,如果不註明,默認就是引用表的主鍵

實際上數據庫中的表結構如下, User 的 addressID 字段關聯着 Address 的 id 字段:

User 表屬性 語義
id 主鍵
addressID 關聯 Address 表主鍵
name 姓名
phone 手機
其他屬性
Address 表屬性 語義
id 主鍵
receiver 收件人
detail 詳細地址
其他屬性

看了上面的表是不是就很清楚了?

很多網上的解釋說 name 指的是外鍵名、實體字段名,其實都不是很準確,容易混淆,還是要動手做一下。

瞭解了JoinColumn 不妨進一步瞭解下 @JoinTable 的 JoinColumn 屬性,這個也是比較容易混淆的。

三、@JoinTable 的 JoinColumn 屬性

@JoinTable 一般和 @ManyToMany 使用,處理多對多關係,需要兩個 Entity 有中間關係表。“一對多”一般不會使用關係表,而選擇將“一”直接作爲“多”的一個屬性。這也是我們學數據庫時聽老師講的常用方法。

JoinTable 有很多屬性,但我們瞭解基本的 JoinColumn 相關屬性即可,和我們上面說的一樣,JoinColumn 實際上指的是數據庫的字段,下面從 《Spring Data JPA 從入門到精通》截取的示例:
在這裏插入圖片描述
看起來好長,但實際上只用到 @JoinTable 只有三個屬性:

  • name:數據庫裏的中間關係表名(blog_tag_relation)
  • joinColumns:當前表在關係表的鏈接字段(blog_id),一般我們會用 id
  • inverseJoinColumn:另一張表在關係表的鏈接字段(tag_id),一般我們會用 id

注意到我們使用 @JoinColumn 指定中間表的列,一定記住它使用的是數據庫字段。對應的表結構如下:

Blog 表屬性 語義
id ID
其他屬性
Tag 表屬性 語義
id ID
其他屬性
blog_tag_relation 表屬性 語義
blog_id Blog 的 ID
tag_id Tag 的 ID

全文結束。如果閱讀了本文後你對如何區分和使用JPA屬性有了更多的認識,請爲我點個贊,讓更多人關注我,這是我不斷髮文分享重要動力。

有問題歡迎留言討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章