JPA:對映單向多對一關聯關係
1.單向多對一是jpa中常用的關聯關係,這裡以訂單和顧客舉例子(多個訂單可以對應同一顧客)
2.顧客實體類程式碼如下:
package com.wayne.helloworld;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
/*
* 如果不新增@Table註解,則表名與實體類名相同
*/
@Table(name="JPA_CUSTOMERS")
@Entity
public class Customer {
private Integer id;
private String lastName;
private String email;
private int age;
private Date createdDate;
private Date birthDay;
@Column(name="ID")
@GeneratedValue(strategy=GenerationType.AUTO)
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="LAST_NAME",length=50,nullable=true)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
//若屬性名與欄位名相同,則不需要填寫註解
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//精度時間戳
@Temporal(TemporalType.TIMESTAMP)
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
@Temporal(TemporalType.DATE)
public Date getBirthDay() {
return birthDay;
}
public void setBirthDay(Date birthDay) {
this.birthDay = birthDay;
}
//工具方法,不需要對映為某個資料庫表的一列
@Transient
public String getInfo(){
return "lastName:"+this.getLastName();
}
@Override
public String toString() {
return "Customer [id=" + id + ", lastName=" + lastName + ", email=" + email + ", age=" + age + ", createdDate="
+ createdDate + ", birthDay=" + birthDay + "]";
}
}
3.訂單程式碼如下:
package com.wayne.helloworld;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Table(name="JPA_ORDERS")
@Entity
public class Order {
private Integer id;
private String orderName;
private Customer customer;
@GeneratedValue
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="ORDER_NAME")
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
/*單向多對一的關聯關係
使用@ManyToOne來對映多對一的關聯關係
使用@JoinColumn來對映外來鍵
name為關聯表的列列名
可使用@ManyToOne的fetch屬性來修改預設的關聯屬性的載入策略*/
@JoinColumn(name="CUSTOMER_ID")
@ManyToOne
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
4.首先測試插入資料:
.執行後資料庫資料已經結構如下:
.執行後控制檯輸出如下:
很明顯,當我們建立臨時的客戶和訂單物件,再做出關聯,最後先插入客戶資料再插入訂單資料,
控制檯輸出的是三條插入語句
.另外一種情況,當我們做出關聯之後,先插入訂單資料然後再插入客戶資料:
.執行後,控制檯輸出如下:
.可以很明顯的看出,首先jpa先插入了order的資料但是外來鍵是Null的,在新增顧客之後再更新為關聯的顧客id
.所以在新增關聯關係的情況下,首先要新增"一"的資料,然後再新增"多"的資料,不然會多執行sql語句,影響效能
5.測試查詢:
控制檯輸出如下:
可見預設情況下,使用左外連線的方式來獲取多的一端的物件和其關聯的一的一端的物件
.在Order實體類中,我們在ManyToOne註解後新增如下,開啟懶載入,只查詢我們需要的物件,如果不查詢顧客的話,
那麼只加載訂單物件:
.然後我們再次執行查詢,控制檯輸出如下:
6.刪除以及更新程式碼如下,這裡不再過多贅述: