将 SQL 查询转换为 Hibernate CriteriaQuery

Convert SQL Query to Hibernate CriteriaQuery

我想将其转换为使用 javax.persistence.criteria.CriteriaBuilder,但不确定该怎么做,非常感谢您的帮助!

SELECT * FROM User u INNER JOIN Teacher t ON t.emp_id = u.emp_id WHERE u.college_id=:college_id AND u.Book.sub_code=:sub_code AND t.lang=:lang

实体管理器的检索取决于您的框架和用例。该解决方案假定您将 collegeIdsubCodelang 作为方法中的给定值。

您为 SELECT 中的 User 创建一个查询,并为此 class 创建一个 Root

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(User.class);

然后,你加入不同的 classes。因为我认为 Book 也是必需的 class,所以我也会加入。您不必提及应该在哪个 ID 上进行连接,因为您已经用注释 @Id.

提到了哪个值是 ID
Join<User, Teacher> teacherJoin = root.join(User_.TEACHER);
Join<User, Book> bookJoin = root.join(User_.BOOK);

可以将不同的WHERE条件添加到条件查询中。对于 link 几个 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 对象

以下示例显示了将上述代码片段合并到一个函数中。

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();
}