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.

YaoFeng
la source
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 .

George Siggouroglou
la source
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);
romain
la source
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));
L. Holanda
la source
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
11

Cette fonctionnalité a été ajoutée dans la version 1.4 M1

Abel Pastur
la source
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);
}
Sagar Misal
la source
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);

Marcos Nunes
la source
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();
}
Thanongsak Chamung
la source
1

Selon le problème DATAJPA-231, la fonctionnalité n'est pas encore implémentée.

Oleksandr Bondarenko
la source
Maintenant, c'est implémenté
Sergey Ponomarev
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

Mark Sholund
la source
0
@Autowired
private UserRepository userRepository;

@RequestMapping("/user/count")
private Long getNumberOfUsers(){
    return userRepository.count();
}
Богдан Ляховецкий
la source
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);
Inzimam Tariq IT
la source