JPA一对多关联关系


/**
* 实体类
*/
package com.jpa.helloword;


import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Cacheable;
import javax.persistence.Entity;
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 org.hibernate.annotations.Cache;

/**
* @author 徐庶
* @date 2016年12月10日
*/
@Cacheable(true)
@Table(name="JPA_CUSTOMERS")
@Entity
public class Customer {
private Integer id;
private String name;
private String email;
private int age;
private Date birth;
private Date createDate;
//一对多
private Set<Order> orders=new HashSet<>();
//使用@JoinColumn来映射外键列的名称
@JoinColumn(name="CUSTOMER_ID")
@OneToMany
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
@Temporal(TemporalType.DATE)
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}

@Temporal(TemporalType.TIMESTAMP)
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
@GeneratedValue(strategy=GenerationType.AUTO)
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

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;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", email=" + email
+ ", age=" + age + ", birth=" + birth + ", createDate="
+ createDate + "]";
}

}


/**
*
*/
package com.jpa.helloword;

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.ManyToOne;
import javax.persistence.Table;

/**
* @author 徐庶
* @date 2016年12月11日
*/
@Table(name="JPA_ORDERS")
@Entity
public class Order {
private Integer id;
private String OrderName;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
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) {
OrderName = orderName;
}
}

测试:


//一对多测试,单向一对多执行保存时,会多出 update语句,因为多的一方插入时不会同时插入外键列。
@Test
public void OneTomany(){
Customer customer=new Customer();
customer.setAge(10);
customer.setName("tom");
customer.setBirth(new Date());
customer.setCreateDate(new Date());
customer.setEmail("tom@q.com");
Order order1=new Order();
order1.setOrderName("TTT");
Order order2=new Order();
order2.setOrderName("YYY");
customer.getOrders().add(order1);
customer.getOrders().add(order2);
//保存
entityManager.persist(customer);
entityManager.persist(order1);
entityManager.persist(order2);
}
//一对多查询时默认使用懒加载方式
//可以使用(fetch=FetchType.EAGER)修改加载策略。
@Test
public void oneTomanyfind(){
Customer customer = entityManager.find(Customer.class, 6);
System.out.println(customer.getName());
System.err.println("------------");
System.out.println(customer.getOrders().size());
}

一对多的保存也可以使用@OneToMany(cascade={CascadeType.PERSIST})注解进行级联保存。


@Test
public void OneTomany(){
Customer customer=new Customer();
customer.setAge(10);
customer.setName("飞鹰");
customer.setBirth(new Date());
customer.setCreateDate(new Date());
customer.setEmail("飞飞@q.com");
Order order1=new Order();
order1.setOrderName("飞飞1");
Order order2=new Order();
order2.setOrderName("飞飞2");
customer.getOrders().add(order1);
customer.getOrders().add(order2);
//保存
entityManager.persist(customer);
//entityManager.persist(order1);
//entityManager.persist(order2);
}


//一对多删除时,若删除一的一端,则会把多的一端的外键置空,然后再删除。
//可以通过@OneToMany(cascade={CascadeType.REMOVE})来修改默认的删除策略。
@Test
public void oneTomanyRemove(){
Customer customer = entityManager.find(Customer.class, 6);
entityManager.remove(customer);

}


默认情况下删除操作打印的sql语句:


Hibernate: 
select
customer0_.id as id1_0_0_,
customer0_.age as age2_0_0_,
customer0_.birth as birth3_0_0_,
customer0_.createDate as createDa4_0_0_,
customer0_.email as email5_0_0_,
customer0_.name as name6_0_0_
from
JPA_CUSTOMERS customer0_
where
customer0_.id=?
Hibernate:
update
JPA_ORDERS
set
CUSTOMER_ID=null
where
CUSTOMER_ID=?
Hibernate:
delete
from
JPA_CUSTOMERS
where
id=?

由上述语句可以看出,先执行了select语句,然后执行update将CUSTOMER_ID置为空,再进行删除操作。



至此JPA的一对多的关系测试完成