jpa 裏用註解進行關係映射
單向多對一關聯
在 pojo 包下添加實體類 CustomerType.java
在 Customer 類中移除 typeId 屬性,添加 CustomerType 屬性
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="typeId" )
private CustomerType type;
測試用例:
@Test
public void testManyToOne() {
// EntitymanagerFactory
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("jpademo");
// MyBatis---SqlSession JPA --- EntityManager
EntityManager entityManager = factory.createEntityManager();
Customer customer= entityManager.find(Customer.class,1);
System.out.println(customer);
}
注意:註解@ManyToOne(fetch=FetchType.EAGER)默認的是立即加載,需要懶加載時候,要加 fetch 參數修改爲 LAZY;可以使用 targetEntity 屬性指定關聯實體類型@ManyToOne(targetEntity=CustomerType.class)
單向一對多的關聯
在 CustomerType.java 中添加 Customer 類型的集合屬性
@OneToMany(targetEntity=Customer.class ,cascade = CascadeType.REMOVE)
@JoinColumn(name=”typeid”)
private Set<Customer> customers = new HashSet<>();
測試用例:
@Test
public void testOneToMany() {
// EntitymanagerFactory
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("jpademo");
// MyBatis---SqlSession JPA --- EntityManager
EntityManager entityManager = factory.createEntityManager();
CustomerType customertype= entityManager.find(CustomerType.class,1);
System.out.println(customertype.getId()+"==="+customertype.getTypeName());
System.out.println("================================");
Set<Customer> customers= customertype.getCustomers();
Iterator iterator= customers.iterator();
while(iterator.hasNext()){
Customer customer= (Customer) iterator.next();
System.out.println(customer.getId()+"==="+customer.getName());
}
}
注意:註解@OneToMany(fetch=FetchType.LAZY)默認的是懶加載,需要懶加載的候,要加 fetch 參數修改,使用@JoinColumn(name=“typeid”) 設置關聯外鍵
雙向的一對多的關聯
CustomerType.java 中
@OneToMany(mappedBy = "type", fetch = FetchType.EAGER ,cascade = CascadeType.REMOVE)
private Set<Customer> customers = new HashSet<>();
CustomerType.java 中
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="typeId" )
private CustomerType type;
注意:
- 在 Customer.java 中使用 mappedBy 設置關聯的外鍵屬性,避免出現中間表
- 雙向關聯關係,兩遍默認都會維護關係,可能衝突,也影響效率,正常情況關係交給“多”的一端維護,一的這端@OneToMany(mappedBy=“type”,這個屬性放棄關係維護
- 一旦使用 mappedBy 屬性,那麼@JoinColumn 這個註解就不能使用了,用了會出錯
測試用例:
@Test
public void testManyToMany() {
// EntitymanagerFactory
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("jpademo");
// MyBatis---SqlSession JPA --- EntityManager
EntityManager entityManager = factory.createEntityManager();
CustomerType customertype= entityManager.find(CustomerType.class,1);
System.out.println(customertype.getId()+"==="+customertype.getTypeName());
System.out.println("================================");
Set<Customer> customers= customertype.getCustomers();
Iterator iterator= customers.iterator();
while(iterator.hasNext()){
Customer customer= (Customer) iterator.next();
System.out.println(customer.getId()+"==="+customer.getName());
}
}
向多對多的關聯
在 pojo 包下添加實體類客戶產品實體類 CustomerProduct.java 和產品實體類
Product.java 並加上 JPA 註解
Customer.java 類中添加 manytomany 註解
@ManyToMany
@JoinTable(name = "customer_product", joinColumns = {@JoinColumn(name =
"customer_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "product_id",
referencedColumnName = "id")})
private Set<Product> productItems = new HashSet<Product>();
解釋: @JoinTable(name=“中間表”,joinColumns={@JoinColumn(name=“當前對象在中間表的外鍵名”,referencedColumnName="
當前對象表的主鍵")},
inverseJoinColumns={@JoinColumn(name="關聯表在中間表的外鍵名
",referencedColumnName=“關聯表的主鍵”)})
Customer 這邊維護關係,Product 就要放棄關係的維護,使用 mappedBy 將維護權交給另外
一方。
Product.java 類中
@ManyToMany(mappedBy = "productItems")
private Set<Customer> customerItem=new HashSet<Customer>();
注意:在真項目開發中,我們處理雙向多對多的關聯,還可以變通來處理,就是將多對多關聯,轉換爲兩個一對多的關聯
其他相關JPA知識及代碼點此處