Мне нужно построить фоновый процесс, который будет периодически обрабатывать все элементы таблицы базы данных.
Поскольку я не могу загрузить все элементы в память, мне нужно разделить базу данных на подчасти. К сожалению, я не могу использовать тип возвращаемого значения JPQL Stream, поскольку в запросе используется сложная логика на основе фильтров, которую невозможно реализовать путем написания запроса JPQL.
Таким образом, я построил следующий критерийный запрос , чтобы вернуть только страницу продуктов. После того как я обработал страницу, как я могу перебирать следующую, пока не обработаю их все?
import org.springframework.data.jpa.repository.query.QueryUtils;
@Repository
@AllArgsConstructor
public class ProductRepositoryImpl implements CustomProductRepository {
private final EntityManager entityManager;
@Override
public Page getProducts(Pageable pageable, /* fields used to filter the results */) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Product.class);
Root root = criteriaQuery.from(Product.class);
List predicates = getPredicates(/* fields used to filter the results */);
criteriaQuery.where(combinePredicatesWithAndStatement(criteriaBuilder, predicates))
.orderBy(QueryUtils.toOrders(pageable.getSort(), root, criteriaBuilder));
List result = entityManager.createQuery(criteriaQuery)
.setFirstResult((int) pageable.getOffset())
.setMaxResults(pageable.getPageSize())
.getResultList();
CriteriaBuilder criteriaBuilderCount = entityManager.getCriteriaBuilder();
CriteriaQuery countQuery = criteriaBuilderCount.createQuery(Long.class);
Root rootCount = countQuery.from(Product.class);
List predicatesCount = getPredicates(/* fields used to filter the results */);
countQuery.select(criteriaBuilderCount.count(rootCount))
.where(combinePredicatesWithAndStatement(criteriaBuilderCount, predicatesCount));
Long totalElements = entityManager.createQuery(countQuery).getSingleResult();
return new PageImpl(result, pageable, totalElements);
}
private List getPredicates(/* fields used to filter the results */) {
List predicates = new ArrayList();
// assemble predicates based on some complex conditions not replicable with JPQL
return predicates;
}
private Predicate combinePredicatesWithAndStatement(CriteriaBuilder criteriaBuilder, List predicates) {
return criteriaBuilder.and(predicates.stream().filter(Objects::nonNull).toArray(Predicate[]::new));
}
}
Подробнее здесь: https://stackoverflow.com/questions/778 ... a-criteria
Как перебрать каждую страницу, возвращаемую критерием JPA? ⇐ JAVA
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как я могу перебрать два списка, а затем добавить каждую пару в кортеж [дубликат]
Anonymous » » в форуме Python - 0 Ответы
- 16 Просмотры
-
Последнее сообщение Anonymous
-