一、单向多对一关系:
 
 
    
  @Entity
 
 
@Table(name="jpa_order")
 
 
class Order {
 
 
private Integer id;
 
 
private String orderName;
 
 
private Customer customer;
 
 
     
 
 
@GeneratedValue(strategy=GenerationType.AUTO)
 
 
@Id
 
 
public Integer getId() {
 
 
return id;
 
 
       }
 
 
public void setId(Integer id) {
 
 
this.id = id;
 
 
        }
 
 
public String getOrderName() {
 
 
return orderName;
 
 
       }
 
 
public void setOrderName(String orderName) {
 
 
this.orderName = orderName;
 
 
       }
 
 
     
 
 
@JoinColumn(name="customer_id")
 
 
@ManyToOne
 
 
public Customer getCustomer() {
 
 
return customer;
 
 
       }
 
 
public void setCustomer(Customer customer) {
 
 
this.customer = customer;
 
 
       }
 
 
 }
 
 
二、单向一对多关系:
 
 
(name="jpa_customer")
 
 
    @Entity
 
 
class Customer {
 
 
private Integer id;
 
 
private String lastName;
 
 
private String email;
 
 
private Integer age;
 
 
private Date birthday;
 
 
private Date createTime;
 
 
private Set<Order> orders = new HashSet<>();
 
 
     
 
 
@GeneratedValue(strategy=GenerationType.AUTO)
 
 
@Id
 
 
public Integer getId() {
 
 
return id;
 
 
       }
 
 
public void setId(Integer id) {
 
 
this.id = id;
 
 
       }
 
 
@Column(name="last_name")
 
 
public String getLastName() {
 
 
return lastName;
 
 
        }
 
 
@Temporal(TemporalType.DATE)
 
 
public Date getBirthday() {
 
 
return birthday;
 
 
       }
 
 
public void setBirthday(Date birthday) {
 
 
this.birthday = birthday;
 
 
       }
 
 
@Temporal(TemporalType.TIMESTAMP)
 
 
public Date getCreateTime() {
 
 
return createTime;
 
 
       }
 
 
public void setCreateTime(Date createTime) {
 
 
this.createTime = createTime;
 
 
       }
 
 
@JoinColumn(name="customer_id")
 
 
@OneToMany(cascade=CascadeType.REMOVE)
 
 
public Set<Order> getOrders() {
 
 
return orders;
 
 
       }
 
 
public void setOrders(Set<Order> orders) {
 
 
this.orders = orders;
 
 
        }
 
 
     }
 
 
插入
 
 
   不管先插入多大一端还是一的一端,最终打印的sql语句数量是一样的,因为是由一的一端维护关联关系,所以在插入多的一端时它并不会保存外键值,只有在持久化之后再另外发送update语句更新多的一端的外键值
 
 
删除
 
 
    多的一端可以随意删除,主要说一下一的一端
 
 
    在单向多对一的时候一的一端是不可以删除的
 
 
    而单项一对多的不同,可以删除一的一端,那么多的一端会被怎么操作呢?根据发出的sql语句可以看出,在默认情况下,删除一的一端,多的一端的外键会被置为null。那么接下来就说一下怎么设置对多的一端的操作。
 
 
 
 
 
   3、在@OneToMany注解中有一个cascade属性,它的值是一个CascadeType类的数组
 
 
ALL级联所有实体状态转换
 
 
 :级联实体持久化操作。
 
 
 :级联实体合并操作。
 
 
 :级联实体删除操作。
 
 
:级联实体刷新操作。
 
 
级联实体分离操作。
 
 
二、双向一对一关系: 一个部门有一个经理,一个经理管一个部门
 
 
 1、department类
 
 
    
  @Entity
 
 
(name="jpa_department")
 
 
class Department {
 
 
@Id
 
 
@GeneratedValue(strategy=GenerationType.AUTO)
 
 
private Integer id;
 
 
@Column(name="dep_name")
 
 
private String depName;
 
 
     
 
 
@JoinColumn(name="manager_id")
 
 
@OneToOne
 
 
private Manager manager;
 
 
    }
 
 
2、Manager类
 
 
    @Entity
 
 
(name="jpa_manager")
 
 
class Manager {
 
 
@Id
 
 
@GeneratedValue(strategy=GenerationType.AUTO)
 
 
private Integer id;
 
 
     
 
 
@OneToOne(mappedBy="manager")
 
 
private String name;
 
 
     
 
 
@OneToOne(mappedBy="manager")
 
 
private Department department;
 
 
     }
 
 
3、插入:
 
 
      Manager manager = new Manager();
 
 
manager.setName("王强");
 
 
          
 
 
department = new Department();
 
 
department.setDepName("销售部");
 
 
          
 
 
manager.setDepartment(department);
 
 
department.setManager(manager);
 
 
          
 
 
entityManager.persist(manager);
 
 
entityManager.persist(department);
 
 
     
  关于插入的顺序,先插入不维护关联关系的一方,即manager(没有外键的一方)
 
 
  
 
 
4、查询:查询维护关联关系的一方(有外键的一方)
 
 
Department dept = entityManager.find(Department.class, 1);
 
 
         System.out.println(dept.getDeptName());
 
 
只想要department,不想要manager。可以用fetch更改为懒加载策略:在department实体类中加入
 
 
@OneToOne(fetch=FetchType.LAZY)
 
 
     private Manager manager;
 
 
 
 
 
5、查询不维护关联关系的一方(没有外键的一方)
 
 
Manager m = entityManager.find(Manager.class, 1);
 
 
     System.out.println

(m.getName());


   运行发现,查询manager时,一定会去查department,即使用fetch改为懒加载策略,结果也是一样的。


   不同的时,如果改为懒加载,将会执行两个sql语句查询。默认情况下是执行一句sql语句关联查询。因此不推荐设置fetch


一定会查询两个对象的原因:



在查询manager表时,没有外键,jpa不知道该怎么处理Manager中的关联对象,因此它一定会去department表中查看有没有相应的记录。

在查询department时,因为有外键,所以jpa很容易的知道该怎么处理关联对象:要么返回一个代理,要么返回对象)