Jak paginować zapytanie JPA

Mam tabelę submission z kolumnami jak ID, Name, Code między innymi nieruchomości. Moim wymogiem jest wyszukanie rekordów na podstawie wymienionych właściwości i zwrócenie stronicowanego zestawu.

To jest pseudokod tego czego szukam:

searchSubmission(searchFilter sf,pageIndex,noOfRecords) {
   query = 'from submisssion where code=sf.code or id=sf.id order by id start_from (pageIndex*noOfRecords) limit noOfRecords'
   return result();
}

Wydaje się, że istnieje wiele opcji, takich jak CriteriaBuilder, NamedQuery, itd. Który jest najskuteczniejszy w tej sytuacji?

Author: Vlad Mihalcea, 2013-04-18

3 answers

Dla wszystkich obiektów zapytań JPA (z wyjątkiem natywnych zapytań SQL), można użyć paginacji za pomocą metod setMaxResults(int) i setFirstResult (int). Na przykład:

  return em.createNamedQuery("yourqueryname", YourEntity.class)
      .setMaxResults(noOfRecords)
      .setFirstResult(pageIndex * noOfRecords));
      .getResultList();

JPA wykona paginację za Ciebie.

Zapytania nazwane są tylko predefiniowane i mogą być buforowane, podczas gdy inne typy są dynamicznie tworzone.
Więc wybór to użycie JPQL w stylu:

Query query = em.createQuery("SELECT s FROM Submission s WHERE s.code = :code or s.id = :id ORDER BY s.id", Submission.class);

Lub CriteriaBuilder api, aby utworzyć podobne zapytanie:

    CriteriaBuilder qb = em.getCriteriaBuilder();
    CriteriaQuery<Submission> cq = qb.createQuery(Submission.class);

    Root<Submission> root = cq.from(Submission.class);
    cq.where( qb.or( 
        qb.equal(root.get("code"), qb.parameter(String.class, "code")),
        qb.equal(root.get("id"), qb.parameter(Integer.class, "id"))
    ));
    Query query = em.createQuery(cq);

Nie zapomnij ustawić wartości parametrów using query.setParameter ("id", sf.id) na przykład.

 32
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-28 04:04:41

Możesz użyć Pageable w metodzie repozytorium

@Repository
public interface StateRepository extends JpaRepository<State, Serializable> {

@Query("select state from State state where state.stateId.stateCode = ?1")
public State findStateByCode(String code, Pageable pageable);

}

I w warstwie usług można utworzyć obiekt Pageable:

@Autowire
StateRepository stateRepository;

public State findStateServiceByCode(String code, int page, int size) {
    Pageable pageable = new PageRequest(page, size);
    Page<Order> statePage = stateRepository.findStateByCode(code, pageable);
    return statePage.getContent();
}
 2
Author: sendon1982,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-09 00:47:29

Jak wyjaśniłem w Ten artykuł , możesz użyć paginacji JPA zarówno dla zapytań encji, jak i natywnego SQL.

Aby ograniczyć rozmiar bazowego zapytania ResultSet, interfejs JPA Query zapewnia setMaxResults metoda .

Poruszanie się po następującej stronie wymaga pozycjonowania wyniku ustawionego w miejscu, w którym zakończyła się ostatnia strona. W tym celu interfejs JPA Query zapewnia setFirstResult metoda .

Używanie paginacji z zapytaniem JPQL wygląda jak następuje:

List posts = entityManager .createQuery( "wybierz p" + "z Post p" + "order by P. createdOn ") .setFirstResult(10) .setMaxResults(10) .getResultList ();

Criteria API jest takie samo, ponieważ musisz utworzyć Query z CriteriaQuery:

CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Post> cq = qb.createQuery(Post.class);

Root<Post> root = cq.from(Post.class);
cq.orderBy(qb.asc(root.get("createdOn")));

List<Post> posts = em
.createQuery(cq)
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
 0
Author: Vlad Mihalcea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-09 15:47:19