Limiter les résultats de requête avec JPA et JPA de données de printemps

Limitation des résultats de requête avec JPA et Spring Data JPA

1. introduction

Dans ce tutoriel, nous allons àlearn about limiting query results avecJPA etSpring Data JPA.

Tout d'abord, nous allons examiner la table que nous voulons interroger ainsi que la requête SQL que nous voulons reproduire.

Ensuite, nous verrons comment y parvenir avec JPA et Spring Data JPA.

Commençons!

2. Les données de test

Ci-dessous, nous avons le tableau que nous allons interroger tout au long de cet article.

La question à laquelle nous voulons répondre est la suivante: «Quel est le premier siège occupé et qui l'occupe?».

Prénom

Nom de famille

Numéro de siège

Jill

Forgeron

50

Eve

Jackson

94

Fred

Bloggs

22

Ricki

Bobbie

36

Siya

Kolisi

85

3. Le SQL

Avec SQL, nous pouvons écrire une requête qui ressemble à ceci:

SELECT firstName, lastName, seatNumber FROM passengers ORDER BY seatNumber LIMIT 1;

4. Configuration JPA

Avec JPA, nous avons d’abord besoin d’une entité pour cartographier notre tableau:

@Entity
class Passenger {

    @Id
    @GeneratedValue
    @Column(nullable = false)
    private Long id;

    @Basic(optional = false)
    @Column(nullable = false)
    private String fistName;

    @Basic(optional = false)
    @Column(nullable = false)
    private String lastName;

    @Basic(optional = false)
    @Column(nullable = false)
    private int seatNumber;

    // constructor, getters etc.
}

Ensuite, nous avons besoin d'une méthode qui encapsule notre code de requête, implémentée ici en tant quePassengerRepositoryImpl#findOrderedBySeatNumberLimitedTo(int limit):

@Repository
class PassengerRepositoryImpl {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List findOrderedBySeatNumberLimitedTo(int limit) {
        return entityManager.createQuery("SELECT p FROM Passenger p ORDER BY p.seatNumber",
          Passenger.class).setMaxResults(limit).getResultList();
    }
}

Dans notre méthode de référentiel, nous utilisons lesEntityManager pour créer unQuery sur lequel nous appelons la méthodesetMaxResults().

Cet appel àQuery#setMaxResults aboutira finalement à l'instruction limit ajoutée au SQL généré:

select
  passenger0_.id as id1_15_,
  passenger0_.fist_name as fist_nam2_15_,
  passenger0_.last_name as last_nam3_15_,
  passenger0_.seat_number as seat_num4_15_
from passenger passenger0_ order by passenger0_.seat_number limit ?

5. Avec Spring Data JPA

Nous pouvons également générer notre code SQL à l'aide de Spring Data JPA.

5.1. first outop

Une façon d'aborder cela est d'utiliser la dérivation de nom de méthode avec les mots-clésfirst outop.

Nous pouvons éventuellement spécifier un nombre comme taille maximale du résultat à retourner. Si nous l'omettons, Spring Data JPA suppose une taille de résultat de 1.

En nous rappelant que nous voulons savoir quel est le premier siège occupé et qui l'occupe, nous pouvons l'obtenir en omettant le numéro de deux manières:

Passenger findFirstByOrderBySeatNumberAsc();
Passenger findTopByOrderBySeatNumberAsc();

Si nous nous limitons à un résultat d'instance, comme ci-dessus, nous pouvons également envelopper le résultat en utilisantOptional:

Optional findFirstByOrderBySeatNumberAsc();
Optional findTopByOrderBySeatNumberAsc();

5.2. Pageable

Alternativement, nous pouvons utiliser un objetPageable:

Page page = repository.findAll(PageRequest.of(0, 1, Sort.by(Sort.Direction.ASC, "seatNumber")));

Si nous jetons un coup d'œil à l'implémentation par défaut deJpaRepository,, leSimpleJpaRepositorywe peut voir qu'il appelle égalementQuery#setMaxResults:

protected  Page < S > readPage(TypedQuery < S > query,
  Class < S > domainClass, Pageable pageable,
  @Nullable Specification < S > spec) {
    if (pageable.isPaged()) {
        query.setFirstResult((int) pageable.getOffset());
        query.setMaxResults(pageable.getPageSize());
    }

    return PageableExecutionUtils.getPage(query.getResultList(), pageable, () -> {
        return executeCountQuery(this.getCountQuery(spec, domainClass));
    });
}

5.3. Comparaison

Ces deux alternatives produiront le code SQL recherché:

select
  passenger0_.id as id1_15_,
  passenger0_.fist_name as fist_nam2_15_,
  passenger0_.last_name as last_nam3_15_,
  passenger0_.seat_number as seat_num4_15_
from passenger passenger0_ order by passenger0_.seat_number asc limit ?

Avecfirst andtop favorisant la convention etPageable favorisant la configuration.

6. Conclusion

La limitation des résultats de requête enJPA est légèrement différente de SQL - nous n'incluons pas le mot-clé limit directement dans nosJPQL.

Au lieu de cela, nous faisons juste un seul appel de méthode àQuery#maxResults ou incluons le mot-cléfirst outop dans notre nom de méthodeSpring Data JPA.

Comme toujours, vous pouvez trouver le codeover on GitHub.