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("[email protected]");
        e1.setPhone("10086");
        e1.setCompany(company);

        Employee e2 = new Employee();
        e2.setName("員工4");
        e2.setEmail("[email protected]");
        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 (?, ?, ?, ?, ?)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章