Spring Data JPA dispose-t-il d'un moyen de compter les entités à l'aide de la résolution de noms de méthode?


127

Spring Data JPA prend en charge le comptage des entités à l'aide de spécifications. Mais y a-t-il un moyen de compter les entités à l'aide de la résolution de noms de méthode? Disons que je veux une méthode countByNamepour compter les entités avec un nom spécifique, tout comme une méthode findByNamepour récupérer toutes les entités avec un nom spécifique.


6
Veuillez accepter l'une des réponses, YaoFeng. J'ai testé Spring Data JPA 1.5.2 et la syntaxe countByName () fonctionne comme le note Abel.
nullPainter

Réponses:


216

Depuis Spring Data 1.7.1.RELEASE, vous pouvez le faire de deux manières différentes,

1) La nouvelle méthode , utilisant la dérivation de requête pour les requêtes de comptage et de suppression. Lisez ceci , (Exemple 5). Exemple,

public interface UserRepository extends CrudRepository<User, Integer> {
    Long countByName(String name);
}

2) L' ancienne méthode , en utilisant l'annotation @Query.
Exemple,

public interface UserRepository extends CrudRepository<User, Integer> {
    @Query("SELECT COUNT(u) FROM User u WHERE u.name=?1")
    Long aMethodNameOrSomething(String name);
}

ou en utilisant l'annotation @Param également,

public interface UserRepository extends CrudRepository<User, Integer> {
    @Query("SELECT COUNT(u) FROM User u WHERE u.name=:name")
    Long aMethodNameOrSomething(@Param("name") String name);
}

Vérifiez également cette réponse .


3
qu'en est-il des autres fonctions d'agrégation telles que somme, moyenne?
lrkwz

La question portait sur la fonction de comptage et non sur la somme ou la moyenne. Les données Spring ne prennent pas encore en charge quelque chose comme la «nouvelle méthode» pour ces fonctions. Vous pourriez utiliser quelque chose comme ça
George Siggouroglou

1
Dans vos deuxième et troisième exemples, je pense que vous auriez besoin d'utiliser "SELECT COUNT (u) ...", car c'est censé être une requête de comptage.
TheChrisPratt

Merci pour votre commentaire. C'etait mon erreur.
George Siggouroglou

Ne pas se tromper, trouvé - commons-lang
NickJ

19

Tant que vous n'utilisez pas la version 1.4, vous pouvez utiliser une annotation explicite:

exemple:

@Query("select count(e) from Product e where e.area.code = ?1")
long countByAreaCode(String code);

3
notez que la méthode doit retourner à la longplace de int, sinon vous obtiendrez une ClassCastException sans aucun indice
Rangi Lin

13

JpaRepository étend également QueryByExampleExecutor. Vous n'avez donc même pas besoin de définir des méthodes personnalisées sur votre interface:

public interface UserRepository extends JpaRepository<User, Long> {
    // no need of custom method
}

Et puis interrogez comme:

User probe = new User();
u.setName = "John";
long count = repo.count(Example.of(probe));

Cette version que j'aime le plus - d'autant plus que je ne pouvais pas me dire comment cela devrait fonctionner selon le docu :-) Vous m'avez sauvé la journée :-) En guise de remarque: les primitives (par exemple int) sont incluses dans la recherche expamle, ie int agesera inclus mais pas défini, mais Integer agesera exclu de l'échantillon (au moins dans Eclipselink)
LeO

Ceci est exactement ce que je cherchais. Je vous remercie!
emrekgn


8

Exemple de travail

@Repository
public interface TenantRepository extends JpaRepository< Tenant, Long > {
    List<Tenant>findByTenantName(String tenantName,Pageable pageRequest);
    long countByTenantName(String tenantName);
}

Appel depuis la couche DAO

@Override
public long countByTenantName(String tenantName) {
    return repository.countByTenantName(tenantName);
}

5

Selon Abel, après la version 1.4 (testée en version 1.4.3.RELEASE), il est possible de faire de cette façon:

public long countByName (nom de chaîne);



2

Merci à tous! Maintenant c'est du travail. DATAJPA-231

Ce serait bien s'il était possible de créer un compte… Par… des méthodes comme find… Par un. Exemple:

public interface UserRepository extends JpaRepository<User, Long> {

   public Long /*or BigInteger */ countByActiveTrue();
}


1

Je ne travaille avec lui que depuis quelques semaines, mais je ne pense pas que cela soit strictement possible, mais vous devriez pouvoir obtenir le même effet avec un peu plus d'effort; écrivez simplement la requête vous-même et annotez le nom de la méthode. Ce n'est probablement pas beaucoup plus simple que d'écrire la méthode vous-même, mais c'est plus propre à mon avis.

Edit: c'est désormais possible selon DATAJPA-231


0
@Autowired
private UserRepository userRepository;

@RequestMapping("/user/count")
private Long getNumberOfUsers(){
    return userRepository.count();
}

1
Cet exemple est hors sujet. L'utilisateur a demandé comment compter le nom du champ countBy et non comment appeler le décompte de base à partir d'un service REST.
Jad B.,

0

Si quelqu'un souhaite obtenir le décompte basé sur plusieurs conditions, voici un exemple de requête personnalisée

@Query("select count(sl) from SlUrl sl where sl.user =?1 And sl.creationDate between ?2 And ?3")
    long countUrlsBetweenDates(User user, Date date1, Date date2);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.