#java #hibernate #hibernate-criteria #criteriaquery
Вопрос:
Я хотел бы преобразовать его, чтобы использовать критерии javax.persistence..Создатель критериев, но не уверен, что делать, любая помощь очень ценится!
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
Ответ №1:
Извлечение менеджера сущностей зависит от вашей платформы и вашего варианта использования. Решение предполагает , что у вас есть collegeId
, subCode
и lang
как указано в вашем методе.
Вы создаете запрос для User
того, что у вас есть в вашем SELECT
, и создаете Root
для этого класса.
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(User.class);
Затем вы присоединяетесь к разным классам. Поскольку я предполагаю, что Book
это также необходимый класс, я бы тоже присоединился к этому. Вам не нужно указывать, с каким идентификатором должны происходить соединения, потому что вы уже упомянули, какое значение является идентификатором с аннотацией @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
дает вам фактическую строку, которая ссылается на Teacher
объект внутри User
.
В следующем примере показаны приведенные выше фрагменты кода, объединенные в функцию.
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();
}