实体管理器的检索取决于您的框架和用例。该解决方案假定您将 collegeId、subCode 和 lang 作为方法中的给定值。
您为SELECT 中的User 创建一个查询,并为这个类创建一个Root。
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(User.class);
然后,你加入不同的班级。因为我假设Book 也是一个需要的课程,所以我也会加入这个课程。您不必提及应该在哪个 ID 上进行连接,因为您已经提到了哪个值是带有注释 @Id 的 ID。
Join<User, Teacher> teacherJoin = root.join(User_.TEACHER);
Join<User, Book> bookJoin = root.join(User_.BOOK);
不同的WHERE 条件可以添加到条件查询中。为了链接多个WHERE 条件,我将条件添加到列表中(最终将它们组合起来)。
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(root.get(User_.COLLEGE_ID), collegeId));
predicates.add(cb.equal(bookJoin.get(Book_.SUB_CODE), subCode));
predicates.add(cb.equal(teacherJoin.get(Teacher_.LANG), lang));
最终,您必须执行构造的查询。
cq
.select(root)
.where(cb.and(predicates.toArray()));
return entityManager.createQuery(cq).getResultList();
以上答案使用 JPA 元模型生成器来防止您将实际参考名称输入为字符串。例如,调用User_.TEACHER 为您提供了实际的字符串,它引用User 中的Teacher 对象。
下面的例子展示了上面的代码sn-ps在一个函数中合并在一起。
public List<User> findAllByCollegeIdAndBookSubCodeAndTeacherLang(
String collegeId,
int subCode,
Lang lang) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(User.class);
Join<User, Teacher> teacherJoin = root.join(User_.TEACHER);
Join<User, Book> bookJoin = root.join(User_.BOOK);
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(root.get(User_.COLLEGE_ID), collegeId));
predicates.add(cb.equal(bookJoin.get(Book_.SUB_CODE), subCode));
predicates.add(cb.equal(teacherJoin.get(Teacher_.LANG), lang));
cq
.select(root)
.where(cb.and(predicates.toArray()));
return entityManager.createQuery(cq).getResultList();
}