Spring Data JPA ha un modo per contare le entità utilizzando la risoluzione del nome del metodo?


127

Spring Data JPA supporta il conteggio delle entità utilizzando le specifiche. Ma ha un modo per contare le entità usando la risoluzione del nome del metodo? Diciamo che voglio un metodo countByNameper contare le entità con un nome specifico, proprio come un metodo findByNameper recuperare tutte le entità con un nome specifico.


6
Per favore accetta una delle risposte, YaoFeng. Ho testato Spring Data JPA 1.5.2 e la sintassi countByName () funziona come le note di Abel.
nullPainter

Risposte:


216

A partire da Spring Data 1.7.1.RELEASE puoi farlo in due modi diversi,

1) Il nuovo modo , utilizzando la derivazione della query sia per contare che per eliminare le query. Leggi questo , (Esempio 5). Esempio,

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

2) Alla vecchia maniera , usando l'annotazione @Query.
Esempio,

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

o utilizzando anche l'annotazione @Param,

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

Controlla anche questo quindi rispondi .


3
che dire di altre funzioni aggregate come somma, media?
lrkwz

La domanda riguardava la funzione di conteggio, non la somma o la media. I dati di primavera non supportano ancora qualcosa come il "nuovo modo" per queste funzioni. Si potrebbe usare qualcosa di simile a questa
George Siggouroglou

1
Nel tuo secondo e terzo esempio, penso che dovresti usare "SELEZIONA CONTO (u) ...", poiché questa dovrebbe essere una query di conteggio.
TheChrisPratt

Grazie per il tuo commento. È stato un mio errore.
George Siggouroglou

Per non preoccuparti, l'ho trovato - commons-lang
NickJ

19

Finché non utilizzi la versione 1.4, puoi utilizzare l'annotazione esplicita:

esempio:

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

3
nota che il metodo dovrebbe restituire longinvece di int, altrimenti otterrai un'eccezione ClassCastException senza alcun indizio
Rangi Lin

13

JpaRepository estende anche QueryByExampleExecutor. Quindi non è nemmeno necessario definire metodi personalizzati sulla tua interfaccia:

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

E poi interroga come:

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

Questa versione mi piace di più, soprattutto perché non ho idea di come dovrebbe funzionare secondo il documento :-) Mi hai salvato la giornata :-) Come osservazione: le primitive (ad es. Int) sono incluse nella ricerca expamle, ie int agesarà incluso anche se non impostato, ma Integer agesarà escluso dal campione (almeno in Eclipselink)
LeO

Questo e 'esattamente quello che stavo cercando. Grazie!
emrekgn


8

Esempio di lavoro

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

Chiamata dal livello DAO

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

5

Secondo Abel, dopo la versione 1.4 (testata nella versione 1.4.3.RELEASE) è possibile fare in questo modo:

public long countByName (String name);



2

Grazie a tutti voi! Adesso è lavoro. DATAJPA-231

Sarebbe bello se fosse possibile creare il conteggio ... Con ... metodi proprio come trova ... Con quelli. Esempio:

public interface UserRepository extends JpaRepository<User, Long> {

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


1

Ci sto lavorando solo da poche settimane, ma non credo che sia strettamente possibile, tuttavia dovresti riuscire a ottenere lo stesso effetto con un po 'più di sforzo; basta scrivere la query da soli e annotare il nome del metodo. Probabilmente non è molto più semplice che scrivere il metodo da soli, ma a mio parere è più pulito.

Modifica: ora è possibile secondo DATAJPA-231


0
@Autowired
private UserRepository userRepository;

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

1
Questo esempio è fuori tema. L'utente ha chiesto come contare in base al nome del campo e non come chiamare il conteggio di base da un servizio REST.
Jad B.

0

Se qualcuno vuole ottenere il conteggio in base a più condizioni, ecco una query personalizzata di esempio

@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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.