С помощью Criteria Builder / Criteria Query можно использовать выбранные поля в операторе where?
Моя конечная цель - позволить интерфейсу применять фильтры к DTO, и я думаю, что самый простой способ - применить эти фильтры к выбранным полям.
Так что, если, например, мой запрос вернул DTO с firstName
(таблица пользователя), lastName
(таблица пользователя) и bookmarked
(подзапрос в другой таблице), я мог бы выполнить свой заданный по умолчанию запрос, а затем применить другое предложение, где, глядя на firstName, lastName и в закладки?
что-то вроде
select
u.firstName as first,
u.lastName as last,
(select CAST(1 AS BIT) from user_bookmark b where b.user_id=u.id as bookmarked)
from user u
where first = 'john' and bookmarked = true; //Dynamic part from UI
У меня работает весь запрос, кроме я не уверен, как отфильтровать результаты на основе выбранных полей.
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<OfficerDTO> cq = cb.createQuery(OfficerDTO.class);
Root<OfficerEntity> root = cq.from(OfficerEntity.class);
Subquery<Long> subquery = null;
subquery = cq.subquery(Long.class);
Root<OfficerBookmarkEntity> subRoot = subquery.from(OfficerBookmarkEntity.class);
System.out.println("************ adding query");
subquery.select(subRoot.get("user").get("id"));
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(subRoot.get("officer").get("id"), root.get("id")));
predicates.add(cb.equal(subRoot.get("user").get("id"), 123456789L));
subquery.where(cb.and(predicates.toArray(new Predicate[]{})));
cq.multiselect(
root.get("firstName").alias("firstName"),
root.get("lastName").alias("lastName"),
subquery.getSelection().isNotNull().alias("bookmarked")
);
TypedQuery<OfficerDTO> q = em.createQuery(cq);
return q.getResultList();
Я знаю, что могу добавить cq.where(cb.equal(root.get("firstName"), "Jane"));
, но это не очень динамично c, и я не могу придумать, как добавить точку в закладке, что-то вроде cq.where(cb.equal(root.get("firstName"), "Jane"), cb.equal(subquery.getSelection().isNotNull(), true) );
не делает не работает, потому что подзапрос там не выполняется.