JPA, как использовать один и тот же критерийQuery Object, чтобы получить список результатов и сделать счетчик выбора - PullRequest
0 голосов
/ 03 апреля 2020

Я использую attributeBuilder для создания критерия Query для определенного типа c.

CriteriaQuery<? extends File> criteriaQuery = criteriaBuilder.createQuery(Folder.class);

Запрос довольно сложный, и мне нужно добавить несколько объединений и т. Д. c.

Мне нужно ограничить результат запроса при использовании метода createQuery entityManager. .

final TypedQuery<? extends File> query = this.entityManager.createQuery(criteriaQuery)
                .setFirstResult(start).setMaxResults(filePerPage);

Но мне также нужно знать, сколько результатов я могу получить без ограничения, потому что оно мне нужно для расчета количества страниц для системы нумерации страниц.

Поэтому я использовал другой критерииQueryObject для создания счетчика выбора

CriteriaQuery<Long> criteriaQueryCount = criteriaBuilder.createQuery(Long.class);

Это работает, но я должен применить те же объединения и те же фильтры, так что я делаю работу дважды.

Например:

//creation of the criteriaBuilders from specific types
CriteriaQuery<? extends File> criteriaQuery = criteriaBuilder.createQuery(Folder.class);

CriteriaQuery<Long> criteriaQueryCount = criteriaBuilder.createQuery(Long.class);

//creation of the roots
Root<? extends File> root = criteriaQuery.from(Folder.class),
                     rootCount = criteriaQuery.from(Folder.class);

//list of predicates feeded next
List<Predicate> criteriaList = new ArrayList<>(),
                criteriaCountList = new ArrayList<>();

//adding a join and the predicates
CriteriaBuilder.In<Long> inTagIds = criteriaBuilder.in(root.join("tags", JoinType.INNER).get("id"));
CriteriaBuilder.In<Long> inTagIdsCount = criteriaBuilder.in(rootCount.join("tags", JoinType.INNER).get("id"));

tags.forEach(t -> {
       inTagIds.value(t.getId());
       inTagIdsCount.value(t.getId());
});

criteriaList.add(inTagIds);
criteriaCountList.add(inTagIds);

.... I have almost 10 others filters like this one.

//generating the requests
criteriaQuery.where(criteriaBuilder.and(criteriaList.toArray(new Predicate[0])));

criteriaQuery.distinct(true);

criteriaQueryCount.select(criteriaBuilder.count(rootCount));

criteriaQueryCount.where(criteriaBuilder.and(criteriaCountList.toArray(new Predicate[0])));

final TypedQuery<? extends File> query = this.entityManager.createQuery(criteriaQuery)
                .setFirstResult(searchDto.start).setMaxResults(this.filePerPage);

Long count = this.entityManager.createQuery(criteriaQueryCount).getSingleResult();

List<? extends File> searchRs = query.getResultList();

Мой вопрос: есть ли более удобный способ сделать это, я хотел бы использовать тот же объект CriteriaQuery и / или тот же root, возможно ли это?

...