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.

YaoFeng
źródło
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 .

George Siggouroglou
źródło
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);
rzymski
źródło
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));
L. Holanda
źródło
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
11

Ta funkcja została dodana w wersji 1.4 M1

Abel Pastur
źródło
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);
}
Sagar Misal
źródło
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);

Marcos Nunes
źródło
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();
}
Thanongsak Chamung
źródło
1

Zgodnie z wydaniem DATAJPA-231 funkcja nie została jeszcze zaimplementowana.

Oleksandr Bondarenko
źródło
Teraz jest zaimplementowany
Sergey Ponomarev
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

Mark Sholund
źródło
0
@Autowired
private UserRepository userRepository;

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