JPQL实现OneToMany关联查询:筛选指定关联值并加载全量关联数据
JPQL实现:筛选参与指定运动的学生并加载其全部关联运动
表关系说明
- 涉及
Student(学生)、Games(运动)两张表 Games表以Student Id为外键关联Student表- 两表为一对多关系:1名学生可选择多项运动
查询规则
- 筛选出所有参与过Cricket(板球)项目的学生
- 返回结果中需加载每名符合条件学生的全部已选运动项,不能仅返回匹配到的Cricket项
测试样例
测试数据集
- Student-1:Football, Cricket
- Student-2:Hockey, Cricket
- Student-3:Volleyball, Football
- Student-4:Cricket
预期输出
- Student-1:Football, Cricket
- Student-2:Hockey, Cricket
- Student-4:Cricket
正确JPQL写法
写法1:基础版(适用于关联集合为急加载的场景)
SELECT DISTINCT s FROM Student s WHERE EXISTS ( SELECT 1 FROM s.games g WHERE g.sportName = 'Cricket' )
写法2:避免N+1查询的优化版(适用于关联集合为懒加载的场景,一次性加载所有关联运动)
SELECT DISTINCT s FROM Student s LEFT JOIN FETCH s.games WHERE EXISTS ( SELECT 1 FROM s.games g WHERE g.sportName = 'Cricket' )
注意事项
- 必须加
DISTINCT关键字:JOIN FETCH会为每个关联的运动生成单独的结果行,一个学生对应多项运动时会返回重复的学生实体,DISTINCT会在JPA层对实体去重,保证返回的学生实体不重复 - 不要使用
JOIN s.games g WHERE g.sportName = 'Cricket'直接过滤的写法:这种写法如果配合JOIN FETCH使用,会将学生关联的运动集合过滤为仅包含Cricket项,不符合返回全部已选运动的要求 - 两种写法返回的学生实体中,
games集合都会包含该学生选择的所有运动项,完全匹配预期输出结果
内容的提问来源于stack exchange,提问作者Rama Krishna
相关产品推荐
相关产品推荐

