JPA学习笔记(二):关联关系映射

关联关系映射

关联关系映射是指实体与实体之间关系的映射,映射关系分为如下:

  • 单向多对一:@ManyToOne
  • 单向一对多:@OneToMany
  • 双向多对一/双向一对多:@ManyToOne+@OneToMany
  • 双向一对一:@OneToOne
  • 双向多对多:@ManyToMany

通过注解配置映射关系,实现实体与实体之间关系的映射。自动生成表、外键约束、中间表等内容,实现关联关系映射。

单向多对一

单向多对一是只在多方配置针对一方映射关系映射的配置方式。
在多方的实体类中,配置方式如下:

  • 使用一方实体类型的成员属性,关联一方实体类;
  • 使用@ManyToOne注解来映射多对一的关联关系;

使用fetch属性配置抓取策略,取值:
FetchType.LAZY:懒加载,关联对象会在用到时才会发起SQL查询;
FetchType.EAGER:立即加载,采用左外连接方式进行多表查询,默认采取。

  • 使用@JoinColumn注解来映射外键,使用name属性指定外键列名;

注意:

  • 在多方的数据表中,使用外键列关联一方数据表的主键(自动生成);
  • 在测试类中,多方使用set方法,来为多方实体对象关联一方实体对象;
  • 会自动生成外键约束,所以删除一方时,如果多方有关联数据,则不可删除。

单向多对一的实现

JPA学习笔记(二):关联关系映射_第1张图片
JPA学习笔记(二):关联关系映射_第2张图片

单向多对一的CRUD

为了方便操作,在实体类中,提供了有参构造方法,但顺便也要提供无参构造方法,因为这是JavaBean的规范,也因为很多技术在操作JavaBean时,默认调用无参构造方法。

Employee xiaobai = new Employee(null,"小白","昆明","男",19,null);
Employee xiaohong = new Employee(null,"小红","太原","女",15,null);
Department department = new Department(null, "设计部", "阿芳");
xiaobai.setDept(department);
xiaohong.setDept(department);
em.persist(xiaobai);
em.persist(xiaohong);
em.persist(department);

单向一对多

单向一对多是只在一方配置针对多方映射关系映射的配置方式。
在一方的实体类中,配置方式如下:

  • 使用集合类型的成员属性,关联多方实体类,保存多方实体类型对象;
  • 使用@OneToMany注解来映射一对多的关联关系;
    • 使用fetch属性配置抓取策略,取值:
      • FetchType.LAZY:懒加载,关联对象会在用到时才会发起SQL查询,默认采取;
      • FetchType.EAGER:立即加载,采用左外连接方式进行多表查询。
    • 使用cascade属性,配置级联策略:默认置空
      • CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)
  • 使用@JoinColumn注解来映射外键,name属性指定多方的外键列名。

注意:

  • 在测试类中,一方使用成员属性集合保存多方实体对象;
  • 同时保存多方、一方实体对象时,多方会使用Update语句更新外键列。

单向一对多的实现

JPA学习笔记(二):关联关系映射_第3张图片
JPA学习笔记(二):关联关系映射_第4张图片

单向一对多中的CRUD

新增一方、多方的代码:

Employee xiaobai = new Employee(null,"小白","昆明","男",19,null);
Employee xiaohong = new Employee(null,"小红","太原","女",15,null);
Department department = new Department(null, "设计部", "阿芳");
xiaobai.setDept(department);
xiaohong.setDept(department);
em.persist(xiaobai);
em.persist(xiaohong);
em.persist(department);

双向多对一、双向一对多

双向多对一是在一方、多方都配置多对一关联关系映射的配置方式。
在双方的配置方式,如前面所示一致。
需要额外考虑的问题是,默认情况,一方、多方都维护依赖关系,一方、多方都会操作外键,导致重复执行UPDATA语句。在JPA的规范中,要求多方来维护关联关系,一方作为被维护方,实现方式如下:

  • 在一方中,放弃使用@JoinColumn注解,放弃一方针对关联关系(外键)的维护。
  • 在一方中的@OneToMany注解中,设置mappedBy属性指定一方在多方中的关联属性名称。
  • 在多方,使用@JoinColumn注解的name属性指定外键名称。

双向一对多、多对一的关联关系维护

JPA学习笔记(二):关联关系映射_第5张图片

双向一对一

双向一对一是在双方都配置一对一关联关系映射的配置方式。
一对一映射,可以采取主键映射或外键映射,这里采用外键映射。
映射关系由一方维护即可,不需双方都维护。负责维护的一方称为维护端,放弃维护的一方,称为被维护端。
配置方式如下:

  • 使用@OneToOne注解来映射一对一关联关系;
  • 在被维护端的@OneToOne注解中,使用mappedBy属性表示当前的一方是被维护端,属性值为另一方中关联当前方的属性名。
  • 在维护端,使用@JoinColumn注解的name属性指定外键列的名称。
  • 在多方@OneToOne注解中,使用fetch属性指定抓取策略,取值:
    • FetchType.LAZY:懒加载,关联对象会在用到时才会发起SQL查询;
    • FetchType.EAGER:立即加载,采用左外连接方式进行多表查询,默认采取。
  • 查询被维护端时,无法使用延迟加载。

双向一对一的实现

JPA学习笔记(二):关联关系映射_第6张图片

双向多对多

双向多对多是在关联的双方的,都维护多对多关联关系映射的配置方式。
在双向多对多关系中,必须指定一个关系维护端,可以通过 @ManyToMany 注释中指定 mappedBy 属性来标识其为关系被维护端。
实现方式采用中间表进行维护,中间表不需要创建实体类,通过双方的描述,自动生成中间表。中间表中的记录,记录了双方主键映射关系。
使用方式如下:

  • 使用@ManyToMany注解配置多对多映射关系。
  • 在维护方,使用@JoinTable来描述中间表的信息,属性如下:
    • Name:指定中间表名称;
    • joinColumns配置中间表映射的详细信息:
@JoinTable(name="中间表名称",
joinColumns=@joinColumn(name=“本类在中间表的外键名",
referencedColumnName=“本类的主键"),
inversejoinColumns=@JoinColumn(name=“对方类在中间表的外键名",
referencedColunName=“对方的主键"))
  • 在被维护方,@ManyToMany注解中,通过mappedBy属性来表示其为被维护方,值为对方关联属性的属性名。

多对多映射的实现

JPA学习笔记(二):关联关系映射_第7张图片
更多文章

你可能感兴趣的:(JPA,笔记)