Jpa之OneToMany

一对多关系介绍

在一对多关系中,我们习惯把一的一方称之为主表,把多的一方称之为从表。在数据库中建立一对多的关系,需要使用数据库的外键约束。
什么是外键?指的是从表中有一列,取值参照主表的主键,这一列就是外键。

一对多数据库关系的建立,如下图所示:
在这里插入图片描述

实体关系建立及映射配置

公司实体(一的一方):

package com.example.jpademo.ono2many.entity;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.util.Set;

@Setter
@Getter
//@Data 会引发堆栈溢出,不推荐使用
@Entity
@Table(name = "company")
public class Company {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    private String name;
    private String address;
    private String industry;
//    @OneToMany(targetEntity = Employee.class)
//    @JoinColumn(name = "company_id",referencedColumnName = "id" )
    @OneToMany(mappedBy = "company",fetch = FetchType.EAGER)
    private Set<Employee> employees;

    @Override
    public String toString() {
        return "Company{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", industry='" + industry + '\'' +
                '}';
    }
}

员工实体(多的一方):

package com.example.jpademo.ono2many.entity;

import lombok.Getter;
import lombok.Setter;


import javax.persistence.*;

@Setter
@Getter
@Entity
@Table(name = "employee")
public class Employee  {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    private String name;
    private String phone;
    private String email;
    @ManyToOne(targetEntity = Company.class)
    @JoinColumn(name = "company_id",referencedColumnName = "id")
    private Company company;


    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

注解说明

@OneToMany
作用:建立一对多的关系映射
属性:

  1. targetEntityClass:指定多的一方的类的字节码(XXX.class);如果从表集合类中指定了具体类型了,不需要使用targetEntity;
  2. mappedBy:指定从表实体类中引用主表对象的名称。mappedBy标签一定是定义在被拥有方的,他指向拥有方;mappedBy的含义,应该理解为,拥有方能够自动维护跟被拥有方的关系,当然,如果从被拥有方,通过手工强行来维护拥有方的关系也是可以做到的;
  3. cascade:指定要使用的级联操作;
  4. fetch:指定是否采用延迟加载,参数值为FetchType.LAZYFetchType.MERGE。默认为FetchType.LAZY,表示懒加载。因为关联的多个对象通常不必从数据库预先读取到内;
  5. orphanRemoval:是否使用孤儿删除,比如在一对多的关系中,Student包含多个book,当在对象关系中删除一个book时,此book即成为孤儿节点。

@ManyToOne
作用:建立多对一的关系
属性:

  1. targetEntityClass:指定一的一方实体类字节码,如果主表实体类中指定了具体类型了,不需要使用targetEntity;
  2. cascade:指定要使用的级联操作;
  3. fetch:指定是否采用延迟加载;
  4. optional:关联是否可选。默认为true。如果设置为false,则必须始终存在非空关系。

@JoinColumn
作用:用于定义主键字段和外键字段的对应关系。
属性:

  1. name:指定外键字段名
  2. referencedColumnName:指定引用主表的主键字段名称
  3. unique:是否唯一。默认值不唯一
  4. nullable:是否允许为空。默认值允许。
  5. insertable:是否允许插入。默认值允许。
  6. updatable:是否允许更新。默认值允许。
  7. columnDefinition:列的定义信息。

一对多的操作

保存操作

  @Test
//    @Transactional  //开启事务
//    @Rollback(false)//设置为不回滚
    public void testAdd2(){
        //先保存一,再保存多
        Company company = new Company();
        company.setName("公司2");
        company.setIndustry("电子");
        company.setAddress("通讯地址02");

        Employee e1 = new Employee();
        e1.setName("员工3");
        e1.setEmail("123456@qq.com");
        e1.setPhone("10086");
        e1.setCompany(company);

        Employee e2 = new Employee();
        e2.setName("员工4");
        e2.setEmail("123456@qq.com");
        e2.setPhone("10086");
        e2.setCompany(company);

//        Set<Employee> employees  = new HashSet<>();
//        employees.add(e1);
//        employees.add(e2);
//        company.setEmployees(employees);
        companyRepository.save(company);

        employeeRepository.save(e1);
        employeeRepository.save(e2);
    }

执行SQL:

Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into company (address, industry, name, id) values (?, ?, ?, ?)
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into employee (company_id, email, name, phone, id) values (?, ?, ?, ?, ?)
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into employee (company_id, email, name, phone, id) values (?, ?, ?, ?, ?)

posted @ 2022-10-30 23:22  寒小韩  阅读(535)  评论(0编辑  收藏  举报