1.顾客实体类代码:
package com.wayne.helloworld;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
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;
private Set<Order> orders=new HashSet<>();
@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();
}
/*映射单向一对多的关系
使用OneToMany来映射一对多的关联关系
使用JoinColumn来映射外键列名称
可以使用@OneToMany的fetch属性来修改默认的加载策略
cascade={CascadeType.REMOVE}级联删除
*/
@JoinColumn(name="CUSTOMER_ID")
@OneToMany(fetch=FetchType.EAGER,cascade={CascadeType.REMOVE})
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
@Override
public String toString() {
return "Customer [id=" + id + ", lastName=" + lastName + ", email=" + email + ", age=" + age + ", createdDate="
+ createdDate + ", birthDay=" + birthDay + "]";
}
}
2.订单实体类代码:
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(fetch=FetchType.LAZY)
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
.注意一点:@JoinColumn的name属性要一致
3.添加数据测试代码以及控制台输出如下:
.先保存"多"的一端,再保存"一"的一端,默认情况下,会多出n条update语句
.先保存"一"的一端,再保存"多"的一端,代码片段以及控制台输出如下:
.可见会多出n/2的update语句.
4.在进行双向"一"对"多"关联关系时,建议使用"多"的一方来维护关联关系,而"一"的一方不维护关系,这样会有效减少sql语句
.让"一"的一端放弃维护关联关系,交给"多"的一端
.这里注意要把@JoinColumn(name="CUSTOMER_ID")注释掉,否则会报错
(注意:若在"一"的一端的@OneToMany中使用mappedBy属性,则@OneToMany端就不能使用@JoinColumn属性)
.运行添加数据代码,控制台如下输出,没有任何update语句: