Spring Boot JPA如何查询@OneToMany自动生成的关联中间表
解决方案
你当前的@OneToMany注解没有配置@JoinColumn,所以JPA默认生成了关联中间表,要查询该中间表有两种常用实现方式:
方案1:通过现有实体关联间接获取(无需新增代码)
如果只是需要获取课程和批次的关联关系,不需要直接对中间表做增删改,直接用现有Course实体的关联属性即可:
- 注入
CourseRepository,调用findById拿到指定Course对象后,直接调用getBatches()就能拿到该课程关联的所有Batch数据,底层会自动关联查询中间表 - 如果要统计所有关联关系,调用
findAll()查询所有Course,遍历取出batches属性即可
方案2:自定义中间表实体直接操作(适合需要直接读写中间表的场景)
如果需要单独查询中间表字段、统计关联数量等场景,可以手动定义中间表对应的实体和持久层:
步骤1:定义联合主键类
import java.io.Serializable; import lombok.Data; @Data public class CoursesBatchesId implements Serializable { // 字段名要和中间表的两个主键字段完全对应 private String courseUuid; private String batchUuid; }
步骤2:定义中间表实体
import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Table(name = "courses_batches") // 与自动生成的中间表名保持一致 @Data @NoArgsConstructor @AllArgsConstructor @IdClass(CoursesBatchesId.class) public class CoursesBatches { @Id @Column(name = "courseUuid") // 与你提到的中间表字段名一致 private String courseUuid; @Id @Column(name = "BatchUuid") // 注意大小写要和实际表字段匹配 private String batchUuid; }
步骤3:定义中间表持久层接口
import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; import java.util.Optional; public interface CoursesBatchesRepository extends JpaRepository<CoursesBatches, CoursesBatchesId> { // 自定义查询:根据课程ID查所有关联的批次ID List<CoursesBatches> findByCourseUuid(String courseUuid); // 自定义查询:根据批次ID查所属的课程ID Optional<CoursesBatches> findByBatchUuid(String batchUuid); }
之后注入CoursesBatchesRepository就可以直接对中间表做增删改查操作。
额外优化建议
如果你的业务中一个Batch只会属于一个Course,不需要多对多关联,可以修改Course实体的关联注解,取消中间表提升查询效率:
@OneToMany(cascade = CascadeType.ALL) @JoinColumn(name = "course_uuid", referencedColumnName = "uuid") private Set<Batch> batches;
配置后JPA会在Batch表新增course_uuid字段维护关联关系,不会再生成中间表。
内容的提问来源于stack exchange,提问作者Alpit Anand
相关产品推荐
相关产品推荐

