gpt4 book ai didi

java - 只需使用 FK 列而不是相关实体的 ID 即可消除 JPA 查询中的额外联接

转载 作者:行者123 更新时间:2023-11-30 06:57:05 26 4
gpt4 key购买 nike

我有这样的实体关系:

STUDENT many-to-one STUDENT_COURSE one-to-many COURSE

基本上,学生与其类(class)之间存在多对多关系。该关系由 STUDENT_COURSE 表表示。

假设我为 STUDENTSTUDENT_COURSECOURSE 设置了实体,以便:

@Entity
@Table(name = "STUDENT")
public course Student {
@Id
@Column(name = "ID", nullable = false)
private Long id;

@OneToMany(mappedBy = "student")
private Set<StudentCourse> studentCoursees;

// ... other fields and getters and setters
}

@Entity
@Table(name = "COURSE")
public course Course {
@Id
@Column(name = "ID", nullable = false)
private Long id;

@OneToMany(mappedBy = "course")
private Set<StudentCourse> studentCourses;

// ... other fields and getters and setters
}

@Entity
@Table(name = "STUDENT_COURSE")
public course StudentCourse {
@Id
@Column(name = "ID", nullable = false)
private Long id;

@ManyToOne
@JoinColumn(name = "STUDENT_ID", referencedColumnName = "ID")
@NotNull
private Student student;

@ManyToOne
@JoinColumn(name = "COURSE_ID", referencedColumnName = "ID")
@NotNull
private Course course;

// ... other fields and getters and setters
}

然后,我出于搜索目的创建了一个复杂的条件查询,希望所有学生都参加特定类(class)。我有想要添加到限制中的 courseId。在 SQL 中,我会这样做:

select *
from STUDENT, STUDENT_COURSE
where STUDENT.ID = STUDENT_COURSE.STUDENT_ID
and STUDENT_COURSE.COURSE_ID = <courseId>

请注意,我只加入 STUDENTSTUDENT_COURSE。根据如上所述设置的标准和实体,我似乎被迫加入 STUDENTSTUDENT_COURSECOURSE 因为我不STUDENT_COURSE 上没有 courseId 字段:

Join<Person, PersonCourse> personCourse = root.join("personCourses");
Join<PersonCourse, Course> course = personCourse.join("course");
Predicate onlySpecificCourse = builder.equal(course.get("id"), courseId);

这是否只是我应该同时拥有从 StudentCourse 到 Course 的 @ManyToOne 字段以及 StudentCourse 上的 courseId 字段?如果我将 courseId 字段声明为:

@Column(name = "USER_ID", insertable = false, updatable = false)
private String userId;

然后加入变成:

Join<Person, PersonCourse> personCourse = root.join("personCourses");
Predicate onlySpecificCourse = builder.equal(personCourse.get("courseId"), courseId);

如果我这样做,有什么需要注意的问题吗?特别是,在 PersonCourse 实体上同时拥有 courseIdcourse 的 setter 似乎很奇怪。

最佳答案

<小时/>

更新

我正在更新我的答案,以便为您提供解决方案,尽管我不喜欢它。 :-)

但首先,听起来您希望以 OOP 方式执行此操作,但您不想将持久数据视为对象树,因为 Person、PersonCourse 和 Course 都是同一对象的一部分树,但对于某些特殊情况,您可能会想忘记这个事实。您只能将 ORM 推到某个点,之后您将不得不依靠 native SQL。

但是,我将在这里提供一个 ORM 解决方案,您可能不喜欢,所以这里是:

向 PersonCourse 实体添加一个新属性,并将其映射到联接表中的 COURSE_ID 列。但您必须确保在插入和更新中不使用新属性。

@Column(name = "COURSE_ID", insertable = false, updatable = false)
private Long courseId;

现在您可以从方程中删除类(class)根并仅使用上面显示的谓词。

<小时/>

原始答案

如果 STUDENT_CLASS 表除了 STUDENT 和 CLASS 关系的 ID 之外没有其他列,则只需在 Student 和 Class 实体之间使用 @ManyToMany,而不是 @ManyToOne,并且你不需要第三个实体; Hibernate 会为你处理好它。

如果连接表确实有其他列,例如 GRADERATING 列,则使用如下所述的解决方案:Mapping many-to-many association table with extra column(s)

关于java - 只需使用 FK 列而不是相关实体的 ID 即可消除 JPA 查询中的额外联接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41595112/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com