基础pom.xml 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 <?xml version="1.0" encoding="UTF-8"?> <project  xmlns ="http://maven.apache.org/POM/4.0.0"  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"           xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" >     <modelVersion > 4.0.0</modelVersion >      <groupId > cn.idea360</groupId >      <artifactId > jpa-demo</artifactId >      <version > 0.0.1</version >      <name > jpa-demo</name >      <description > jpa-demo</description >      <properties >          <java.version > 1.8</java.version >          <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding >          <project.reporting.outputEncoding > UTF-8</project.reporting.outputEncoding >          <spring-boot.version > 2.6.13</spring-boot.version >      </properties >      <dependencies >          <dependency >              <groupId > org.springframework.boot</groupId >              <artifactId > spring-boot-starter-data-jpa</artifactId >          </dependency >          <dependency >              <groupId > org.springframework.boot</groupId >              <artifactId > spring-boot-starter-web</artifactId >          </dependency >          <dependency >              <groupId > com.h2database</groupId >              <artifactId > h2</artifactId >              <scope > runtime</scope >          </dependency >          <dependency >              <groupId > org.projectlombok</groupId >              <artifactId > lombok</artifactId >              <optional > true</optional >          </dependency >          <dependency >              <groupId > org.springframework.boot</groupId >              <artifactId > spring-boot-starter-test</artifactId >              <scope > test</scope >          </dependency >      </dependencies >      <dependencyManagement >          <dependencies >              <dependency >                  <groupId > org.springframework.boot</groupId >                  <artifactId > spring-boot-dependencies</artifactId >                  <version > ${spring-boot.version}</version >                  <type > pom</type >                  <scope > import</scope >              </dependency >          </dependencies >      </dependencyManagement >      <build >          <plugins >              <plugin >                  <groupId > org.apache.maven.plugins</groupId >                  <artifactId > maven-compiler-plugin</artifactId >                  <version > 3.8.1</version >                  <configuration >                      <source > 1.8</source >                      <target > 1.8</target >                      <encoding > UTF-8</encoding >                  </configuration >              </plugin >              <plugin >                  <groupId > org.springframework.boot</groupId >                  <artifactId > spring-boot-maven-plugin</artifactId >                  <version > ${spring-boot.version}</version >                  <configuration >                      <mainClass > cn.idea360.jpa.JpaDemoApplication</mainClass >                      <skip > true</skip >                  </configuration >                  <executions >                      <execution >                          <id > repackage</id >                          <goals >                              <goal > repackage</goal >                          </goals >                      </execution >                  </executions >              </plugin >          </plugins >      </build >  </project > 
 
  配置文件application.properties 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 server.port =8080 spring.h2.console.settings.web-allow-others =true spring.h2.console.path =/h2-console spring.h2.console.enabled =true spring.h2.console.settings.trace =true spring.datasource.url =jdbc:h2:file:./data/jpa-h2 spring.datasource.username =san spring.datasource.password =spring.datasource.driver-class-name =org.h2.Driver spring.jpa.database-platform =org.hibernate.dialect.H2Dialect spring.jpa.show-sql =true spring.jpa.hibernate.ddl-auto =update 
 
  使用 @ManyToOne进行单向关联 
场景:一个部门里有多个员工。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package  cn.idea360.jpa.entity;import  lombok.Data;import  javax.persistence.*;import  java.io.Serializable;@Data @Entity @Table(name = "hr_employee") public  class  Employee  implements  Serializable   {    @Id      @GeneratedValue(strategy= GenerationType.IDENTITY)      @Column(name = "id")      private  Integer employeeId;     @Column(name = "employee_name")      private  String employeeName;     @ManyToOne(cascade = CascadeType.ALL)      @JoinColumn(name="departmentId")      private  Department department; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package  cn.idea360.jpa.entity;import  lombok.Data;import  javax.persistence.*;import  java.io.Serializable;@Data @Entity @Table(name = "hr_department") public  class  Department  implements  Serializable   {    @Id      @GeneratedValue(strategy= GenerationType.IDENTITY)      @Column(name = "id")      private  Integer departmentId;     @Column(name = "department_name")      private  String departmentName; } 
 
在这样的设定下, 是由Employee维护对Department的参考来维持多对一的关系,Department并没有意识到Employee的存在,而在存储时,由于设定了CascadeType.ALL,所以直接存储Employee实例时,所参考的Department也会一并被存储。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package  cn.idea360.jpa.repository;import  cn.idea360.jpa.entity.Department;import  cn.idea360.jpa.entity.Employee;import  com.fasterxml.jackson.databind.ObjectMapper;import  lombok.extern.slf4j.Slf4j;import  org.junit.jupiter.api.Test;import  org.springframework.boot.test.context.SpringBootTest;import  javax.annotation.Resource;import  javax.transaction.Transactional;import  java.util.Arrays;@Slf4j @SpringBootTest class  EmployeeRepositoryTest   {    @Resource      private  DepartmentRepository departmentRepository;     @Resource      private  EmployeeRepository employeeRepository;     @Resource      private  ObjectMapper objectMapper;          @Test      @Transactional      void  addAndGetEmployee ()  throws  Exception  {         Department department = new  Department();         department.setDepartmentName("技术部" );         Employee employee1 = new  Employee();         employee1.setEmployeeName("张三" );         employee1.setDepartment(department);         Employee employee2 = new  Employee();         employee2.setEmployeeName("李四" );         employee2.setDepartment(department);         employeeRepository.saveAll(Arrays.asList(employee1, employee2));         Department department1 = departmentRepository.findById(1 ).get();         log.info("db department: {}" , objectMapper.writeValueAsString(department1));         Employee employee = employeeRepository.getById(2 );         log.info("db employee: {}" , objectMapper.writeValueAsString(employee));     } } 
 
日志输出:
1 2 3 4 5 Hibernate: insert into hr_department (id, department_name) values (default, ?) Hibernate: insert into hr_employee (id, department_id, employee_name) values (default, ?, ?) Hibernate: insert into hr_employee (id, department_id, employee_name) values (default, ?, ?) 2023-06-11 13:36:19.592  INFO 35924 --- [           main] c.i.j.repository.EmployeeRepositoryTest  : db department: {"departmentId":1,"departmentName":"技术部"} 2023-06-11 13:36:19.595  INFO 35924 --- [           main] c.i.j.repository.EmployeeRepositoryTest  : db employee: {"employeeId":2,"employeeName":"李四","department":{"departmentId":1,"departmentName":"技术部"}} 
 
  使用 @OneToMany进行单向关联 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package  cn.idea360.jpa.entity;import  lombok.Data;import  javax.persistence.*;import  java.io.Serializable;import  java.util.List;@Data @Entity @Table(name = "hr_department") public  class  Department  implements  Serializable   {    @Id      @GeneratedValue(strategy= GenerationType.IDENTITY)      @Column(name = "id")      private  Integer departmentId;     @Column(name = "department_name")      private  String departmentName;     @OneToMany(cascade = CascadeType.ALL)           @JoinColumn(name = "department_id")      private  List<Employee> employees; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package  cn.idea360.jpa.entity;import  lombok.Data;import  javax.persistence.*;import  java.io.Serializable;@Data @Entity @Table(name = "hr_employee") public  class  Employee  implements  Serializable   {    @Id      @GeneratedValue(strategy= GenerationType.IDENTITY)      @Column(name = "id")      private  Integer employeeId;     @Column(name = "employee_name")      private  String employeeName; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 package  cn.idea360.jpa.repository;import  cn.idea360.jpa.entity.Department;import  cn.idea360.jpa.entity.Employee;import  com.fasterxml.jackson.databind.ObjectMapper;import  lombok.extern.slf4j.Slf4j;import  org.junit.jupiter.api.Test;import  org.springframework.boot.test.context.SpringBootTest;import  org.springframework.test.annotation.Rollback;import  javax.annotation.Resource;import  javax.transaction.Transactional;import  java.util.Arrays;@Slf4j @SpringBootTest class  EmployeeRepositoryTest   {    @Resource      private  DepartmentRepository departmentRepository;     @Resource      private  EmployeeRepository employeeRepository;     @Resource      private  ObjectMapper objectMapper;          @Test      @Transactional      @Rollback(value = false)      void  addAndGetDepartment ()  throws  Exception  {         Employee employee1 = new  Employee();         employee1.setEmployeeName("张三" );         Employee employee2 = new  Employee();         employee2.setEmployeeName("李四" );         Department department = new  Department();         department.setDepartmentName("技术部" );         department.setEmployees(Arrays.asList(employee1, employee2));         departmentRepository.save(department);         Department department1 = departmentRepository.findById(1 ).get();         log.info("db department: {}" , objectMapper.writeValueAsString(department1));                  log.info("db department.employees: {}" , objectMapper.writeValueAsString(department1.getEmployees()));         Employee employee = employeeRepository.getById(2 );         log.info("db employee: {}" , objectMapper.writeValueAsString(employee));     } } 
 
输出
1 2 3 4 5 6 7 8 9 10 Hibernate: insert into hr_department (id, department_name) values (default, ?) Hibernate: insert into hr_employee (id, employee_name) values (default, ?) Hibernate: insert into hr_employee (id, employee_name) values (default, ?) Hibernate: select department0_.id as id1_0_0_, department0_.department_name as departme2_0_0_ from hr_department department0_ where department0_.id=? Hibernate: select employees0_.department_id as departme3_1_0_, employees0_.id as id1_1_0_, employees0_.id as id1_1_1_, employees0_.employee_name as employee2_1_1_ from hr_employee employees0_ where employees0_.department_id=? 2023-06-11 14:53:40.497  INFO 37827 --- [           main] c.i.j.repository.EmployeeRepositoryTest  : db department: {"departmentId":1,"departmentName":"技术部","employees":[{"employeeId":1,"employeeName":"张三"},{"employeeId":2,"employeeName":"李四"}]} 2023-06-11 14:53:40.498  INFO 37827 --- [           main] c.i.j.repository.EmployeeRepositoryTest  : db department.employees: [{"employeeId":1,"employeeName":"张三"},{"employeeId":2,"employeeName":"李四"}] 2023-06-11 14:53:40.500  INFO 37827 --- [           main] c.i.j.repository.EmployeeRepositoryTest  : db employee: {"employeeId":2,"employeeName":"李四"} Hibernate: update hr_employee set department_id=? where id=? Hibernate: update hr_employee set department_id=? where id=? 
 
  @OneToMany和@ManyToOne同时使用:双向的关联 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package  cn.idea360.jpa.entity;import  lombok.Data;import  javax.persistence.*;import  java.io.Serializable;@Data @Entity @Table(name = "hr_employee") public  class  Employee  implements  Serializable   {    @Id      @GeneratedValue(strategy= GenerationType.IDENTITY)      @Column(name = "id")      private  Integer employeeId;     @Column(name = "employee_name")      private  String employeeName;     @ManyToOne(cascade = CascadeType.ALL)      @JoinColumn(name="departmentId")      private  Department department; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package  cn.idea360.jpa.entity;import  lombok.Data;import  javax.persistence.*;import  java.io.Serializable;import  java.util.List;@Data @Entity @Table(name = "hr_department") public  class  Department  implements  Serializable   {    @Id      @GeneratedValue(strategy= GenerationType.IDENTITY)      @Column(name = "id")      private  Integer departmentId;     @Column(name = "department_name")      private  String departmentName;     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)      private  List<Employee> employees; } 
 
测试还有问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 package  cn.idea360.jpa.repository;import  cn.idea360.jpa.entity.Department;import  cn.idea360.jpa.entity.Employee;import  com.fasterxml.jackson.databind.ObjectMapper;import  lombok.extern.slf4j.Slf4j;import  org.junit.jupiter.api.Test;import  org.springframework.boot.test.context.SpringBootTest;import  javax.annotation.Resource;import  javax.transaction.Transactional;import  java.util.Arrays;@Slf4j @SpringBootTest class  EmployeeRepositoryTest   {    @Resource      private  DepartmentRepository departmentRepository;     @Resource      private  EmployeeRepository employeeRepository;     @Resource      private  ObjectMapper objectMapper;          @Test      @Transactional      void  addAndGetDepartment ()  throws  Exception  {         Employee employee1 = new  Employee();         employee1.setEmployeeName("张三" );         Employee employee2 = new  Employee();         employee2.setEmployeeName("李四" );         Department department = new  Department();         department.setDepartmentName("技术部" );         department.setEmployees(Arrays.asList(employee1, employee2));         departmentRepository.save(department);         Department department1 = departmentRepository.findById(1 ).get();         log.info("db department: {}" , objectMapper.writeValueAsString(department1));                  log.info("db department.employees: {}" , objectMapper.writeValueAsString(department1.getEmployees()));         Employee employee = employeeRepository.getById(2 );         log.info("db employee: {}" , objectMapper.writeValueAsString(employee));     }     @Test      @Transactional      void  addAndGetEmployee ()  throws  Exception  {         Department department = new  Department();         department.setDepartmentName("技术部" );         Employee employee1 = new  Employee();         employee1.setEmployeeName("张三" );         employee1.setDepartment(department);         Employee employee2 = new  Employee();         employee2.setEmployeeName("李四" );         employee2.setDepartment(department);         employeeRepository.saveAll(Arrays.asList(employee1, employee2));         Department department1 = departmentRepository.findById(1 ).get();         log.info("db department: {}" , objectMapper.writeValueAsString(department1));                  log.info("db department.employees: {}" , objectMapper.writeValueAsString(department1.getEmployees()));         Employee employee = employeeRepository.getById(2 );         log.info("db employee: {}" , objectMapper.writeValueAsString(employee));     } } 
 
  参考