前言
本節開始我們正式步入關系映射的講解,對於關系映射,在.NET或NET Core對於相關實體大多我們稱之為主體和依賴體,而在java中稱之為源實體和目標實體,只是叫法不同,本質上大同小異,文中若有錯誤之處,還望指正。
one to one關系映射
一對一關聯可以是單向或雙向的,在單向關聯中,源實體具有一個關系字段,該關系字段引用目標實體,並且源實體的表包含外鍵,在雙向關聯中,每個實體(即源實體和目標實體)都有一個相互引用的關系字段,並且目標實體的表包含外鍵,源實體必須使用mappedBy屬性來定義雙向一對一映射,接下來我們分別來看單向關聯和雙向關聯。
單向關聯
這里我們分別給出所用到的兩個對象Post和PostDetail,一篇博客發表只對應此篇博客詳情,如下:
@Entity public class Post { @Id @GeneratedValue private Long id; private String title; @OneToOne @JoinColumn(name = "post_detail_id") private PostDetail postDetail; }
@Entity public class PostDetail { @Id @GeneratedValue private Long id; @Column(name = "created_on") private Date createdOn; @Column(name = "created_by") private String createdBy; public PostDetail() { } public PostDetail(String createdBy) { createdOn = new Date(); this.createdBy = createdBy; } }
如上單向關聯中,通過源實體(Post)中的關系字段post_detail_id來引用目標實體,且此字段作目標實體(PostDetail)的外鍵,很明顯像這種情況不符合實際情況,因為postdetail依賴於post。
雙向關聯
即便是一對一關系也會存在所屬關系即目標實體依賴於源實體,所以上述post和postdetail關系是雙向的,如果關系是雙向的,則非擁有方(目標實體)必須使用屬性mappedBy來指定擁有方的關系字段或屬性。此時我們將post實體和postdetail實體修改成如下,而postdetail添加源實體。
@Entity public class Post { @OneToOne(mappedBy = "post") private PostDetail postDetail; } @Entity public class PostDetail { @OneToOne private Post post; }
上述我們在Post通過mappedBy添加了對目標實體PostDetail的所屬關系,同時在PostDetail添加了對Post的關聯,此時我們可以看到默認生成的外鍵為post_id即(源實體名稱 + '_' + id),若需要修改外鍵名稱,直接通過注解@JoinColumn顯式指定外鍵名稱,比如如下指定為custom_post_id。
分析到這里為止,其實對於一對一關系映射配置還是非常簡單,我們只需要根據業務搞清楚所屬關系,然后通過mappedBy指定,最終可以默認或顯式指定外鍵名稱,有的童鞋可能就問了,要是我想將實體PostDetail中的外鍵post_id也作為主鍵呢,也就是說將post_id作為共享主鍵,此時我們應該怎么辦呢?此時實體PostDetail中的主鍵id將不再是自動生成,去除自動生成注解,然后通過注解@MapsId來指定源實體,改造后的實體PostDetail如下
@Entity public class PostDetail { @Id private Long id; @OneToOne @MapsId private Post post; }
雖然我們達到了共享主鍵的目的,但是在PostDetail表中其主鍵名稱為post_id,如果感覺不太友好或者不太好理解,那就繼續通過注解@JoinColumn指定名稱為id,如下:
@Entity public class PostDetail { @Id private Long id; @OneToOne @MapsId @JoinColumn(name = "id") private Post post; }
總結
本節我們詳細講解了一對一關系映射,無論是單向關聯還是雙向關聯根據實際業務而定,大部分情況下需要通過注解@mappedBy來進行雙向關聯,同時呢,我們也可以通過注解@MapsId來配置共享主鍵。好了,本節到此結束,下一節我們進入一對多關系映射的講解。