(转载)Jpa配置一对多关系

database

链接: https://www.cnblogs.com/a-small-lyf/p/10699326.html

 

在网上查了很多关于jpa一对多表关联的操作,踩了很多坑,今天终于解决了

下面上一下我自己的代码,记录一下

老师和学生(一对多关系)

首先搭建环境,添加依赖包

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.lyf</groupId>

<artifactId>one-to-more</artifactId>

<version>1.0-SNAPSHOT</version>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.1.3.RELEASE</version>

</parent>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>5.1.47</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<version>1.16.22</version>

</dependency>

</dependencies>

</project>

编写数据库配置文件

spring.datasource.url=jdbc:mysql://localhost:3306/jpa?serverTimezone=UTC

spring.datasource.username=root

spring.datasource.password=08186912

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update

spring.jpa.show-sql=true

spring.jpa.database=mysql

实体类

package com.lyf.pojo;

import lombok.Data;

import javax.persistence.*;

/**

* @Date:2019-04-12

* @Description:com.lyf.pojo

* @version:1.0

*/

@Data

@Entity

@Table(name = "tb_student")

publicclass Student {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

@Column(name = "s_id")

private Long sId;

@Column(name = "s_name")

private String sName;

/**

* 多个学生对应一个老师

* 注解形式配置多对一

* 1,配置表关系

* 2,配置外键

*/

@ManyToOne(targetEntity = Teacher.class)

@JoinColumn(name = "s_t_id",referencedColumnName = "t_id")

private Teacher teacher;

}

package com.lyf.pojo;

import lombok.Data;

import javax.persistence.*;

import java.util.HashSet;

import java.util.Set;

/**

* @Date:2019-04-12

* @Description:教师和学生是一对多

*/

@Data

@Entity

@Table(name = "tb_teacher")

public class Teacher {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

@Column(name = "t_id")

private Long tId;

@Column(name = "t_name")

private String tName;

//配置老师和学生一对多

/**

* 注解配置多表关系

* 1,声名关系

* 2,配置外键,或者中间表

* OneToMany配置一对多

* targetEntity设置对应的实体类的类型

* JoinColumn 配置外键

* name:外键的名称,

* referencedColumnName参照的主表的主键字段名称

*/

@OneToMany(targetEntity = Student.class)

@JoinColumn(name = "s_t_id",referencedColumnName = "t_id")

private Set<Student> students = new HashSet<>();

}

 

springboot启动类(引导类)

package com.lyf;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**

* @Date:2019-04-12

* @Description:com.lyf

* @version:1.0

*/

@SpringBootApplication

publicclass App {

publicstaticvoid main(String[] args) {

SpringApplication.run(App.class,args);

}

}

启动引导类,查看数据库会发现表生成成功

dao层代码就不上了,继承JpaRepository就行了

 

接下来我们进行保存操作

 

package com.lyf;

import com.lyf.dao.StudentDao;

import com.lyf.dao.TeacherDao;

import com.lyf.pojo.Student;

import com.lyf.pojo.Teacher;

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;

/**

* @Date:2019-04-12

* @Description:com.lyf

* @version:1.0

*/

@SpringBootTest

@RunWith(SpringRunner.class)

publicclass OneToMoreTest {

@Autowired

private TeacherDao teacherDao;

@Autowired

private StudentDao studentDao;

@Test

publicvoid addTest(){

Student student = new Student();

student.setSName("老篮孩i");

Teacher teacher = new Teacher();

teacher.setTName("刘老师");

//关联学生和老师,添加学生信息时,还需添加外键的值

student.setTeacher(teacher);

studentDao.save(student);

teacherDao.save(teacher);

}

}

 

结果报错了,发现我是先保存的学生信息,再保存的老师信息,此时数据库中并没有老师的信息,给学生关联老师信息肯定是有问题的

报错信息

 

org.springframework.dao.InvalidDataAccessApiUsageException: 

  org.hibernate.TransientPropertyValueException:

     object references an unsaved transient instance - save the transient instance before flushing : com.lyf.pojo.Student.teacher -> com.lyf.pojo.Teacher;

      nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException:

        object references an unsaved transient instance - save the transient instance before flushing :

          com.lyf.pojo.Student.teacher -> com.lyf.pojo.Teacher

 学生表记录插入了,老师表是空的

 

 

 

改成

 

package com.lyf;

import com.lyf.dao.StudentDao;

import com.lyf.dao.TeacherDao;

import com.lyf.pojo.Student;

import com.lyf.pojo.Teacher;

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;

/**

* @Date:2019-04-12

* @Description:com.lyf

* @version:1.0

*/

@SpringBootTest

@RunWith(SpringRunner.class)

publicclass OneToMoreTest {

@Autowired

private TeacherDao teacherDao;

@Autowired

private StudentDao studentDao;

@Test

publicvoid addTest(){

Student student = new Student();

student.setSName("老篮孩i");

Teacher teacher = new Teacher();

teacher.setTName("刘老师");

//关联学生和老师,添加学生信息时,还需添加外键的值

student.setTeacher(teacher);

//要先保存主表信息

teacherDao.save(teacher);

studentDao.save(student);

}

}

 控制台信息,很显然成功了

Hibernate: alter table tb_student add constraint FKsojy7bicq68v21slcq9mtwtou foreign key (s_t_id) references tb_teacher (t_id)

2019-04-12 23:29:42.036 INFO 10980 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit "default"

2019-04-12 23:29:42.748 INFO 10980 --- [ main] com.lyf.OneToMoreTest : Started OneToMoreTest in 7.77 seconds (JVM running for 9.806)

Hibernate: insert into tb_teacher (t_name) values (?)

Hibernate: insert into tb_student (s_name, s_t_id) values (?, ?)

查看数据库也没有问题

同样我们通过Teacher表也能完成关联操作,保存也是没有问题的

@Test

publicvoid addTest1(){

Student student = new Student();

student.setSName("老篮孩i1");

Teacher teacher = new Teacher();

teacher.setTName("刘老师1");

//通过主表来添加关联

teacher.getStudents().add(student);

studentDao.save(student);

teacherDao.save(teacher);

}

 控制打印信息

Hibernate: insert into tb_student (s_name, s_t_id) values (?, ?)

Hibernate: insert into tb_teacher (t_name) values (?)

Hibernate: update tb_student set s_t_id=? where s_id=?

 

学生类和老师类都添加类外键的配置,都具备外键的维护,那么我们这里可以通过学生找到老师,也能通过老师找到学生,这是一种双向关系

如果只配置一方,那就是单向的关系,只能通过指定的一方找到另一方

以上是 (转载)Jpa配置一对多关系 的全部内容, 来源链接: utcz.com/z/533539.html

回到顶部