我们如何使用 Criteria Query 在 Spring JPA 中查询一对多关系
How we query one to many relation in Spring JPA using Criteria Query
场景是:
实体学生
ID
姓名
列出课程
实体课程
ID
姓名
学生
现在我需要正在学习课程的学生名单'Programming'
如何使用 Criteria Query 实现此目的。
试试这个:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Student> cq = cb.createQuery(Student.class);
Root<Student> rootStudent = cq.from(Student.class);
Join<Student,Course> joinCourse = rootStudent.join("courses",JoinType.INNER);
cq.where(cb.equals(joinCourse.get("Name"),"Proggraming"));
cq.select(rootStudent);
List<Student> res = entityManager.createQuery(cq).getResultList();
在这个例子中,我假设您已经很好地建模了 JPA 实体,包括双向关系。如果是 API,也建议您使用 pojos 而不是将 JPA 实体返回到 Web 部件,为此您应该使用 multiselect 而不是 select 并指定您想要获取的每个字段,但作为第一个近似值,它是有效的。
还建议对 JPA 实体使用元模型,而不是通过名称为 (join, get methods ..)
的字符串访问属性
在这种情况下,进行子查询没有意义,我更改查询以通过子查询查找课程 Proggraming1 或 Proggraming2 的学生(我仍然更喜欢通过过滤连接来完成此操作而不使用子查询),它将是这样的:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Student> cq = cb.createQuery(Student.class);
Root<Student> rootStudent = cq.from(Student.class);
Join<Student,Course> joinCourse = rootStudent.join("courses",JoinType.INNER);
Subquery<Long> subqueryIdCourse = cq.subquery(Long.class);
Root<Course> rootCourseSq = subqueryIdCourse.from(Course.class);
subqueryIdCourse.where(
cb.or(
cb.equals(rootCourseSq.get("Name"),"Proggraming1"),
cb.equals(rootCourseSq.get("Name"),"Proggraming2")))
subqueryIdCourse.select(rootCourseSq.get("ID"))
cq.where(joinCourse.get("ID").in(subqueryIdCourse.getSelection()));
cq.select(rootStudent);
List<Student> res = entityManager.createQuery(cq).getResultList();
场景是: 实体学生 ID 姓名 列出课程
实体课程 ID 姓名 学生
现在我需要正在学习课程的学生名单'Programming'
如何使用 Criteria Query 实现此目的。
试试这个:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Student> cq = cb.createQuery(Student.class);
Root<Student> rootStudent = cq.from(Student.class);
Join<Student,Course> joinCourse = rootStudent.join("courses",JoinType.INNER);
cq.where(cb.equals(joinCourse.get("Name"),"Proggraming"));
cq.select(rootStudent);
List<Student> res = entityManager.createQuery(cq).getResultList();
在这个例子中,我假设您已经很好地建模了 JPA 实体,包括双向关系。如果是 API,也建议您使用 pojos 而不是将 JPA 实体返回到 Web 部件,为此您应该使用 multiselect 而不是 select 并指定您想要获取的每个字段,但作为第一个近似值,它是有效的。
还建议对 JPA 实体使用元模型,而不是通过名称为 (join, get methods ..)
的字符串访问属性在这种情况下,进行子查询没有意义,我更改查询以通过子查询查找课程 Proggraming1 或 Proggraming2 的学生(我仍然更喜欢通过过滤连接来完成此操作而不使用子查询),它将是这样的:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Student> cq = cb.createQuery(Student.class);
Root<Student> rootStudent = cq.from(Student.class);
Join<Student,Course> joinCourse = rootStudent.join("courses",JoinType.INNER);
Subquery<Long> subqueryIdCourse = cq.subquery(Long.class);
Root<Course> rootCourseSq = subqueryIdCourse.from(Course.class);
subqueryIdCourse.where(
cb.or(
cb.equals(rootCourseSq.get("Name"),"Proggraming1"),
cb.equals(rootCourseSq.get("Name"),"Proggraming2")))
subqueryIdCourse.select(rootCourseSq.get("ID"))
cq.where(joinCourse.get("ID").in(subqueryIdCourse.getSelection()));
cq.select(rootStudent);
List<Student> res = entityManager.createQuery(cq).getResultList();