web-dev-qa-db-fra.com

setMaxResults pour l'annotation Spring-Data-JPA?

J'essaie d'intégrer Spring-Data-JPA à mon projet. Une chose qui me déroute est comment puis-je obtenir setMaxResults (n) par annotation?

par exemple, mon code:

public interface UserRepository extends CrudRepository<User , Long>
{
  @Query(value="From User u where u.otherObj = ?1 ")
  public User findByOhterObj(OtherObj otherObj);
}

Je n'ai besoin que de retourner one (and only one) User de otherObj, mais je ne trouve pas le moyen d'annoter les maxResults. Quelqu'un peut-il me donner un indice?

(mysql se plaint:

com.mysql.jdbc.JDBC4PreparedStatement@5add5415: select user0_.id as id100_, user0_.created as created100_ from User user0_ where user0_.id=2 limit ** NOT SPECIFIED **
WARN  util.JDBCExceptionReporter - SQL Error: 0, SQLState: 07001
ERROR util.JDBCExceptionReporter - No value specified for parameter 2

)

J'ai trouvé un lien: https://jira.springsource.org/browse/DATAJPA-147 , j'ai essayé mais j'ai échoué. Cela ne semble pas possible maintenant? Pourquoi une fonctionnalité aussi importante n'est-elle pas intégrée à Spring-Data?

Si j'implémente cette fonctionnalité manuellement:

public class UserRepositoryImpl implements UserRepository

Je dois implémenter des tonnes de méthodes prédéfinies dans CrudRepository, ce serait terrible.

environnements: spring-3.1, spring-data-jpa-1.0.3.RELEASE.jar, spring-data-commons-core-1.1.0.RELEASE.jar

105
smallufo

À compter de Spring Data JPA 1.7.0 (train de sortie Evans).

Vous pouvez utiliser les nouveaux mots-clés Top et First qui vous permettent de définir des méthodes de requête comme celles-ci:

findTop10ByLastnameOrderByFirstnameAsc(String lastname);

Spring Data limitera automatiquement les résultats au nombre que vous avez défini (la valeur par défaut est 1 si elle est omise). Notez que l'ordre des résultats devient pertinent ici (soit par le biais d'une clause OrderBy comme dans l'exemple, soit en passant un paramètre Sort à la méthode). En savoir plus sur cela dans l'article de blog couvrant nouvelles fonctionnalités du train de versions de Spring Data Evans ou dans le documentation .

Pour les versions précédentes

Pour récupérer uniquement les tranches de données, Spring Data utilise l’abstraction de pagination qui vient avec une interface Pageable du côté demandeur ainsi qu’une abstraction Page du côté des résultats. Pour que vous puissiez commencer avec

public interface UserRepository extends Repository<User, Long> {

  List<User> findByUsername(String username, Pageable pageable);
}

et l'utiliser comme ça:

Pageable topTen = new PageRequest(0, 10);
List<User> result = repository.findByUsername("Matthews", topTen);

Si vous avez besoin de connaître le contexte du résultat (quelle page correspond-il réellement? S'agit-il de la première? Combien y en a-t-il au total?), Utilisez Page comme type de résultat:

public interface UserRepository extends Repository<User, Long> {

  Page<User> findByUsername(String username, Pageable pageable);
}

Le code client peut alors faire quelque chose comme ceci:

Pageable topTen = new PageRequest(0, 10);
Page<User> result = repository.findByUsername("Matthews", topTen);
Assert.assertThat(result.isFirstPage(), is(true));

Cela ne signifie pas que nous allons déclencher une projection du nombre de requêtes à exécuter si vous utilisez Page comme type de résultat car nous devons connaître le nombre total d’éléments permettant de calculer les métadonnées. Au-delà de cela, assurez-vous de doter la PageRequest d'informations de tri afin d'obtenir des résultats stables. Sinon, vous risquez de déclencher la requête deux fois et d'obtenir des résultats différents même si les données n'ont pas été modifiées.

166
Oliver Drotbohm

Si vous utilisez Java 8 et Spring Data 1.7.0, vous pouvez utiliser des méthodes par défaut si vous souhaitez associer une annotation @Query à la définition du maximum de résultats:

public interface UserRepository extends PagingAndSortingRepository<User,Long> {
  @Query("from User u where ...")
  List<User> findAllUsersWhereFoo(@Param("foo") Foo foo, Pageable pageable);

  default List<User> findTop10UsersWhereFoo(Foo foo) {
    return findAllUsersWhereFoo(foo, new PageRequest(0,10));
  }

}
94
Wim Deblauwe

Il existe un moyen de fournir l'équivalent de "un setMaxResults (n) par annotation" comme suit:

public interface ISomething extends JpaRepository<XYZ, Long>
{
    @Query("FROM XYZ a WHERE a.eventDateTime < :before ORDER BY a.eventDateTime DESC")
    List<XYZ> findXYZRecords(@Param("before") Date before, Pageable pageable);
}

Cela devrait faire l'affaire, lorsqu'un pageable est envoyé en paramètre. Par exemple, pour récupérer les 10 premiers enregistrements, vous devez définir pageable sur cette valeur:

new PageRequest(0, 10)
27
ncaralicea

tilisez Spring Data Evans (1.7.0 RELEASE)

la nouvelle version de Spring Data JPA avec une autre liste de modules, nommée ensemble Evans , permet d’utiliser les mots-clés Top20 et First pour limiter le résultat de la requête,

afin que vous puissiez maintenant écrire

List<User> findTop20ByLastname(String lastname, Sort sort);

ou

List<User> findTop20ByLastnameOrderByIdDesc(String lastname);

ou pour un seul résultat

List<User> findFirstByLastnameOrderByIdDesc(String lastname);
21
azerafati

Le meilleur choix pour moi est la requête native:

@Query(value="SELECT * FROM users WHERE other_obj = ?1 LIMIT 1", nativeQuery = true)
User findByOhterObj(OtherObj otherObj);
12
GKislin

Si votre classe @Repository s'étend JpaRepository, vous pouvez utiliser l'exemple ci-dessous.

int limited = 100;
Pageable pageable = new PageRequest(0,limited);
Page<Transaction> transactionsPage = transactionRepository.findAll(specification, pageable);
return transactionsPage.getContent();

getContent retourne un List<Transaction>.

4
Luis Camargo

Il est également possible d'utiliser @QueryHints. Exemple ci-dessous utilise org.Eclipse.persistence.config.QueryHints # JDBC_MAX_ROWS

@Query("SELECT u FROM User u WHERE .....")
@QueryHints(@QueryHint(name = JDBC_MAX_ROWS, value = "1"))
Voter findUser();
4
kraken