Czy Spring Data JPA ma jakikolwiek sposób zliczania elementów za pomocą rozwiązywania nazw metod?


127

Spring Data JPA obsługuje liczenie jednostek przy użyciu specyfikacji. Ale czy ma jakikolwiek sposób zliczania jednostek przy użyciu rozpoznawania nazw metod? Powiedzmy, że chcę, aby metoda countByNameliczyła jednostki o określonej nazwie, tak jak metoda findByNamedo pobierania wszystkich jednostek o określonej nazwie.


6
Proszę, zaakceptuj jedną z odpowiedzi, YaoFeng. Przetestowałem Spring Data JPA 1.5.2 i składnia countByName () działa jak notatki Abela.
nullPainter

Odpowiedzi:


216

Od wersji Spring Data 1.7.1.RELEASE można to zrobić na dwa różne sposoby:

1) Nowy sposób , wykorzystujący wyprowadzanie zapytań zarówno do zliczania, jak i usuwania zapytań. Przeczytaj to (przykład 5). Przykład,

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

2) Stary sposób , używając adnotacji @Query.
Przykład,

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

lub używając również adnotacji @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);
}

Sprawdź też to, więc odpowiedz .


3
a co z innymi funkcjami agregującymi, takimi jak suma, średnia?
lrkwz

Pytanie dotyczyło funkcji liczenia, a nie sumy czy średniej. Dane Spring nie obsługują jeszcze czegoś takiego jak „nowy sposób” dla tych funkcji. Można użyć coś jak ten
George Siggouroglou

1
Myślę, że w drugim i trzecim przykładzie należałoby użyć „SELECT COUNT (u)…”, ponieważ ma to być zapytanie zliczające.
TheChrisPratt

Dziękuję za Twój komentarz. To był mój błąd.
George Siggouroglou

Nie gniewaj się, znalazłem to - commons-lang
NickJ

19

Dopóki nie używasz wersji 1.4, możesz użyć wyraźnej adnotacji:

przykład:

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

3
zwróć uwagę, że metoda powinna zwrócić longzamiast int, w przeciwnym razie otrzymasz ClassCastException bez żadnych wskazówek
Rangi Lin,

13

JpaRepository rozszerza również QueryByExampleExecutor. Nie musisz więc nawet definiować niestandardowych metod w swoim interfejsie:

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

A następnie zapytanie takie jak:

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

Tę wersję lubię najbardziej - zwłaszcza, że ​​nie mogłem wskazać, jak to powinno działać zgodnie z dokumentem :-) Uratowałeś mi dzień :-) Jako uwaga: prymitywy (np. Int) są uwzględnione w wyszukiwaniu expamle, tzn. int agezostanie uwzględniony, chociaż nie ustawiony, ale Integer agezostanie wykluczony z próbki (przynajmniej w Eclipselink)
LeO

To jest dokładnie to, czego szukałem. Dziękuję Ci!
emrekgn


8

Przykład roboczy

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

Wywołanie z warstwy DAO

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

5

Według Abla po wersji 1.4 (testowanej w wersji 1.4.3.RELEASE) można zrobić w ten sposób:

public long countByName (nazwa ciągu);



2

Dziękuję wam wszystkim! Teraz jest praca. DATAJPA-231

Byłoby miło, gdyby można było stworzyć licznik… Metodami takimi jak znajdź… Jednymi. Przykład:

public interface UserRepository extends JpaRepository<User, Long> {

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


1

Pracuję nad tym dopiero od kilku tygodni, ale nie wierzę, że jest to całkowicie możliwe, jednak powinieneś być w stanie uzyskać ten sam efekt przy nieco większym wysiłku; po prostu napisz zapytanie samodzielnie i dodaj adnotację do nazwy metody. Prawdopodobnie nie jest to dużo prostsze niż samodzielne napisanie metody, ale moim zdaniem jest czystsza.

Edycja: jest teraz możliwa zgodnie z DATAJPA-231


0
@Autowired
private UserRepository userRepository;

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

1
Ten przykład jest poza tematem. Użytkownik zapytał, jak policzyć według nazwy pola, a nie jak wywołać podstawowy licznik z usługi REST.
Jad B.

0

Jeśli ktoś chce uzyskać liczbę na podstawie wielu warunków, oto przykładowe zapytanie niestandardowe

@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);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.