單向 OneToOne
-
單向一對一是關聯關系映射中最簡單的一種,簡單地說就是可以從關聯的一方去查詢另一方,卻不能反向查詢。
- @OneToOne注解隻用于關系的發出端,同時定義一個接收端類型的字段屬性;
-
單向的一對一關系在資料庫中是以外鍵的形式被映射的,
-
其中關系的發出端存儲一個指向關系的接收端的一個外鍵。
-
預設情況下這個外鍵的字段名稱,是以它指向的表的名稱加下劃線“_”加“ID”組成的。
-
當然我們也可以根據我們的喜好來修改這個字段,修改的辦法就是使用 @JoinColumn 這個注解
- @OneToOne注解
-
@Target({ElementType.METHOD, ElementType.FIELD})
-
@Retention(RetentionPolicy.RUNTIME)
-
public @interface OneToOne {
-
Class targetEntity() default void.class;
-
CascadeType[] cascade() default {};
-
FetchType fetch() default FetchType.EAGER;
-
boolean optional() default true;
-
String mappedBy() default "";
-
boolean orphanRemoval() default false;
-
}
-
# targetEntity屬性表示預設關聯的實體類型,預設為目前标注的實體類;
-
# cascade屬性表示與此實體一對一關聯的實體的聯級樣式類型。聯級樣式上當對實體進行操作時的政策。
-
說明:在定義關系時經常會涉及是否定義Cascade(級聯處理)屬性,擔心造成負面影響.
-
·不定義,則對關系表不會産生任何影響
-
·CascadeType.PERSIST (級聯建立)
-
·CascadeType.REMOVE (級聯删除)
-
·CascadeType.REFRESH (級聯重新整理)
-
·CascadeType.MERGE (級聯更新)中選擇一個或多個。
-
·還有一個選擇是使用CascadeType.ALL ,表示選擇全部四項
-
# fetch屬性是該實體的加載方式,有兩種:LAZY和EAGER。
-
# optional屬性表示關聯的實體是否能夠存在null值。預設為true,表示可以存在null值。如果為false,則要同時配合使用@JoinColumn标記。
-
# mappedBy屬性用于雙向關聯實體時,标注在不儲存關系的實體中。
-
在四種關聯關系
-
關聯指定列(@JoinColumn)
-
# @JoinColumn用于注釋表中的字段,與@Column不同的是它要儲存表與表之間關系的字段;
-
# name屬性是用來标記表中對應的字段的名稱。
-
name=關聯的表的名稱 + "_" + 關聯表主鍵的字段名如果不設定name的值,預設情況下,name的取值規則如下:
-
# 預設情況下,關聯的實體的主鍵一般用來做外鍵的。如果不想用主鍵作為外鍵,則需要設定referencedColumnName屬性,
-
@JoinColumn(name="address_id", referencedColumnName="ref_id")如:
-
# @JoinColumn可以與@OneToOne、@ManyToOne或@ManyToMany标記同時使用。
雙向 OneToOne
-
雙向關系有一方為關系的發出端,另一方是關系的反端,也就是“Inverse”端(接收端)。
-
@OneToOne注解,發出端和接收端都要使用,同時定義一個接收端類型的字段屬性;
-
同時@OneToOne注解中的“mappedBy”屬性,這個在雙向關系的“Inverse”端是必需的
單向 OneToMany
-
單向關系的一對多
-
@OneToMany 注解隻用于關系的發出端(即“一”的一方),
-
同時關系的發出端--定義一個集合類型的接收端的字段屬性
-
在一對多關聯關系映射中,預設是以中間表的方式來映射這種關系的。
-
中間表的名稱為關系的擁有端和 Inverse 端中間用下劃線連接配接。
-
中間表的字兩個字段分别為兩張表的得表名加下劃線“_”加 ID 組成。
-
當然我們也可以改表這種預設的中間表的映射方式,我們可以在關系的擁有端使用 @JoinClolum 來使用外鍵的方式映射這個關系。
示例
-
假設有兩個表,訂單表和産品表,訂單跟産品的關系是一對多的關系,那麼在JPA中怎樣表示一對多的關系呢?實體關系一對多映射有兩種方式:
- 外鍵關聯
-
//訂單表
-
@Entity
-
@Table(name = "orders")
-
public class Order {
-
@Id
-
@GeneratedValue(strategy = GenerationType.AUTO)
-
private Long id;
-
@OneToMany(cascade = {CascadeType.ALL})
-
@JoinColumn(name = "order_id")
-
private List<Product> productList;
-
...
-
}
-
//産品表
-
@Entity
-
@Table(name = "product")
-
public class Product {
-
@Id
-
@GeneratedValue(strategy = GenerationType.AUTO)
-
private Long id;
-
...
-
這樣在表product中會增加一列order_id
- 表關聯【預設方式】
-
/訂單表
-
@Entity
-
@Table(name = "orders")
-
public class Order {
-
@Id
-
@GeneratedValue(strategy = GenerationType.AUTO)
-
private Long id;
-
@OneToMany(cascade = {CascadeType.ALL})
-
@JoinTable(name = "order_has_product", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")},inverseJoinColumns = {@JoinColumn(name = "product_id", referencedColumnName = "id")})
-
private List<Product> productList;
-
...
-
}
-
joinColumns指定中間表中關聯自己ID的字段,inverseJoinColumns表示中間表中關聯對方ID的字段
-
這樣在product表中不會增加任何外鍵,而是建立了一張order_has_product表
雙向 OneToMany
-
雙向一對多關系
-
@OneToMany(mappedBy='發出端實體名稱小寫') 注解用于關系的發出端(即“一”的一方),
-
同時關系的發出端--定義一個集合類型的接收端的字段屬性,
-
@ManyToOne注解用于關系的接收端端(即“多”的一方),
-
同時關系的接收端--定義一個發出端的字段屬性,
單向 ManyToMany
-
多對多關聯關系中隻能通過中間表的方式進行映射。
-
@ManyToMany 注解用于關系的發出端
-
同時關系的發出端--定義一個集合類型的接收端的字段屬性;
-
關系的接收端,不需要做任何定義;
雙向 ManyToMany
-
@ManyToMany 注解用于關系的發出端和接收端
-
同時關系的發出端和接收端--定義一個集合類型的接收端的字段屬性;
-
關系的接收端,@ManyToMany(mappedBy='集合類型發出端實體的字段名稱');
參考來源:https://www.ibm.com/developerworks/cn/java/j-lo-jparelated/#icomments