阳光沙滩
让学习编程变得简单
Spring Data JPA多表关系之一对多
发表于 2020-03-17    阅读次数 126

Spring Data JPA多表关系之一对多

我们使用Spring data 操作数据库特别方便,增删改查基本的方法都有了。对于单表来说,结合sql语句,基本上可以满足项目单表操作需求。

那么多表怎么操作呢?比如一对多,举个例子

一个员工在一家公司上班,一个公司有很多员工。

这里面我们涉及到公司表,员工表

那么我们就看看怎么实现一对多吧。

员工里有属于哪一家公司的关系,有一个外键约束。

创建数据表

公司表

CREATE TABLE tb_company(
	`id` INTEGER PRIMARY KEY auto_increment,
	`name` varchar(50) NOT NULL,
	`address` VARCHAR(128) NOT null
);

工人表

CREATE TABLE tb_employee(
	`id` integer PRIMARY KEY auto_increment,
	`name` varchar(32) NOT NULL,
	`age` INTEGER,
	`gender` CHAR(1) NOT NULL,
	`company_id` INTEGER NOT NULL,
	CONSTRAINT `fk_tb_employee_company_id` FOREIGN KEY (`company_id`) REFERENCES `tb_company` (`id`)
);

对应的实体类创建

公司实体类

package com.sunofbeach.security.domain;

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

@Entity
@Table(name = "tb_company")
public class Company {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

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

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

    /**
     * 一个公司有很多员工吧,所以可以使用一个集合来保存
     */
    //配置关系
    @OneToMany(targetEntity = Employee.class, fetch = FetchType.EAGER)
    //company_id 表示的是外键名称,referencedColumnName 表示的是参照主表主键字段
    @JoinColumn(name = "company_id", referencedColumnName = "id")
    private Set<Employee> employees = new HashSet<>();

    public Set<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(Set<Employee> employees) {
        this.employees = employees;
    }

    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 String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

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

员工表

package com.sunofbeach.security.domain;

import javax.persistence.*;

@Entity
@Table(name = "tb_employee")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

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

    @Column(name = "age")
    private Integer age;

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

    @Column(name = "company_id")
    private Integer companyId;

    @ManyToOne(targetEntity = Company.class)
    @JoinColumn(name = "company_id", referencedColumnName = "id", insertable = false, updatable = false)
    private Company company;

    public Company getCompany() {
        return company;
    }

    public void setCompany(Company company) {
        this.company = company;
    }

    public Integer getCompanyId() {
        return companyId;
    }

    public void setCompanyId(Integer companyId) {
        this.companyId = companyId;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

测试CRUD

添加公司

package net.sunofbeach.test;


import com.sunofbeach.security.SecurityApplication;
import com.sunofbeach.security.dao.CompanyDao;
import com.sunofbeach.security.domain.Company;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SecurityApplication.class)
public class TestDao {

    @Autowired
    private CompanyDao companyDao;

    @Test
    public void testAddCompany() {
        Company company = new Company();
        company.setAddress("Shenzhen");
        company.setName("sunofbeach Inc");
        companyDao.save(company);
    }

}

后面的话只写方法部分啦

添加员工

 @Test
    public void testAddEmployee() {
        Company company = companyDao.findOneByName("Alibaba Inc");
        Employee employee = new Employee();
        employee.setAge(28);
        employee.setCompanyId(company.getId());
        employee.setGender("m");
        employee.setName("Jack");
        employeeDao.save(employee);
    }

这里的结果如下,我使用sql查询一下,然后再使用java代码去查询

图片描述

公司加了这么几个

工人加了这些:

图片描述

代码进行查询

查询一个工人

   @Test
    public void testFindEmployee() {
        Employee jack = employeeDao.findOneByName("jack");
        System.out.println("jack -- > " + jack);
    }

结果如下:

jack -- > Employee{id=5
, name='Jack'
, age=28
, gender='m'
, companyId=6
, company=Company{id=6
, name='Alibaba Inc'
, address='HangZhou'}}

查找公司

    @Test
    public void testFindCompany() {
        Company company = companyDao.findOneByName("sunofbeach Inc");
        System.out.println("company -- >  " + company);
        Set<Employee> employees = company.getEmployees();
        for (Employee employee : employees) {
            System.out.println("employee -- > " + employee);
        }
    }

测试结果

company -- >  Company{id=4
, name='sunofbeach Inc'
, address='Shenzhen'}
employee -- > Employee{id=1
, name='Li si'
, age=28
, gender='m'
, companyId=4
, company=Company{id=4
, name='sunofbeach Inc'
, address='Shenzhen'}}
employee -- > Employee{id=2
, name='Zhang san'
, age=28
, gender='f'
, companyId=4
, company=Company{id=4
, name='sunofbeach Inc'
, address='Shenzhen'}}

到这里我们就不删除了哈,一对多的关系就搞定了,后面我们再去看看多对多的怎么整吧。

这些都不用记,用得上的时候,看看。写着写着就会了。