使用 Java 11、Spring Boot 和 Spring Data JPA
概述
我想使用 Spring Data JPA 访问 mysql 数据库中的 3 个连接表。为简单起见,我们称它们为学生、课程和性能报告。
这是我的数据类:
@Entity
@Table(name = "student")
@Data
public class Student {
@Id
@Column(name = "student_id")
private Long studentId;
@Column(name = "student_name")
private String studentName;
@OneToMany(mappedBy = "student", fetch = FetchType.EAGER,
cascade = CascadeType.ALL)
private List<PerformanceReport> performanceReports;
}
@Entity
@Table(name = "course")
@Data
public class Course {
@Id
@Column(name = "course_id")
private Long courseId;
@Column(name = "course_name")
private String courseName;
}
@Entity
@Table(name = "performance_report")
@Data
public class PerformanceReport {
@Id
@Column(name = "performance_report_id")
private Long performanceReportId;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "student_id", nullable = false)
// JsonBackReference needed to prevent infinite recursion.
@JsonBackReference
private Student student;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "course_id", nullable = false)
private Course course;
@Column(name = "grade")
private String grade;
@Column(name = "attendance")
private String attendance;
}
这是我的学生存储库:
public interface StudentRepository extends JpaRepository<Student, Long> {
Optional<Student> findById(Long studentId);
}
调用 StudentRepository.findById 会产生一个像这样的对象:
{
"studentId": 1,
"studentName": "Spongebob Squarepants",
"performanceReports": [
{
"performanceReportId": 5473,
"course": {
"courseId": 643,
"courseName": "Boating 101"
},
"grade": "F",
"attendance": "100%"
},
{
"performanceReportId": 4723,
"course": {
"courseId": 346,
"courseName": "Grilling 101"
},
"grade": "A+",
"attendance": "100%"
}
]
}
问题
我还想执行此操作的逆操作,以便查询 Course 并获取如下对象:
{
"courseId": 346,
"courseName": "Grilling 101",
"performanceReports": [
{
"performanceReportId": 4723,
"student": {
"studentId": 1,
"studentName": "Spongebob Squarepants"
},
"grade": "A+",
"attendance": "100%"
},
{
"performanceReportId": 4774,
"student": {
"studentId": 4,
"studentName": "Squidward Tentacles"
},
"grade": "C-",
"attendance": "72%"
}
]
}
我不能用我当前的实体结构来做到这一点。
Course如果我以与我相同的方式设置连接Student- 通过添加一个@OneToManyinCourse并将 a 添加@JsonBackReference到第二个@ManyToOnein PerformanceReport- 我将不会Student在我的结果中获得任何数据。它还将阻止Course数据流向Student查询。如果我删除@JsonBackReference注释,我会得到无限递归和 StackOverflow 错误。
我尝试创建单独的实体来解决这些情况。我从 中删除了连接Student并将其放在扩展的类中Student。Course然后我对and做同样的事情PerformanceReport。这不仅会导致新的错误,而且非常混乱。它还要求我创建单独的存储库来处理这些扩展类。
一定会有更好的办法。
我正确地接近这个吗?Spring Data JPA 是完成此类任务的最佳方式吗?如果我想查询Student或Course根本不使用任何连接怎么办?
当然,对于每种可能的情况,我都不需要新实体。如何自定义连接不同查询的表的方式?