JPA学习笔记(9)——映射双向一对一关联关系

双向一对一关联关系

一个部门有一个经理,一个经理管一个部门

Department实体类

package com.jpa.helloworld2;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Table(name="T_DEPARTMENT")
@Entity
public class Department {

    @Column(name="ID")
    @GeneratedValue
    @Id
    private Integer id;

    @Column(name="DEPT_NAME")
    private String deptName;

    @JoinColumn(name="MANAGER_ID")
    @OneToOne
    private Manager manager;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    public Manager getManager() {
        return manager;
    }

    public void setManager(Manager manager) {
        this.manager = manager;
    }

}

Manager实体类

package com.jpa.helloworld2;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Table(name="T_MANAGER")
@Entity
public class Manager {

    @Column(name="ID")
    @GeneratedValue
    @Id
    private Integer id;

    @Column(name="NAME")
    private String name;

    @OneToOne(mappedBy="manager")
    private Department department;

    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 Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

}

关于mappedBy的使用,在前面的博客有讲到。

插入

Manager manager = new Manager();
manager.setName("mgr1");

Department department = new Department();
department.setDeptName("deptName1");

manager.setDepartment(department);
department.setManager(manager);

entityManager.persist(manager);
entityManager.persist(department);

关于插入的顺序,先插入不维护关联关系的一方,即manager(没有外键的一方)

查询

查询维护关联关系的一方(有外键的一方)

Department dept = entityManager.find(Department.class, 1);
System.out.println(dept.getDeptName());

发现执行了两次sql语句,既查询了department,也查询了manager
JPA学习笔记(9)——映射双向一对一关联关系_第1张图片

但我们此时只想要department,不想要manager。可以用fetch更改为懒加载策略:

在department实体类中

@OneToOne(fetch=FetchType.LAZY)
private Manager manager;

查询不维护关联关系的一方(没有外键的一方)

Manager m = entityManager.find(Manager.class, 1);
System.out.println(m.getName());

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

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

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

  • 在查询manager表时,没有外键,jpa不知道该怎么处理Manager中的关联对象,因此它一定会去department表中查看有没有相应的记录。
  • 在查询department时,因为有外键,所以jpa很容易的知道该怎么处理关联对象:要么返回一个代理,要么返回对象)

你可能感兴趣的:(JPA)