O Spring Data JPA tem alguma maneira de contar entidades usando a resolução de nomes de métodos?

125

O Spring Data JPA suporta contar entidades usando especificações. Mas ele tem alguma maneira de contar entidades usando a resolução de nomes de métodos? Digamos que eu queira um método countByNamepara contar entidades com nome específico, assim como um método findByNamepara buscar todas as entidades com nome específico.

YaoFeng
fonte
6
Por favor, aceite uma das respostas, YaoFeng. Testei o Spring Data JPA 1.5.2 e a sintaxe countByName () funciona como observa Abel.
usar o seguinte comando

Respostas:

214

No Spring Data 1.7.1.RELEASE, você pode fazer isso de duas maneiras diferentes,

1) A nova maneira , usando a derivação de consulta para consultas de contagem e exclusão. Leia isto (Exemplo 5). Exemplo,

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

2) Da maneira antiga , usando a anotação @Query.
Exemplo,

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

ou usando a anotação @Param também,

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

Verifique também esta resposta .

George Siggouroglou
fonte
3
e outras funções agregadas, como soma, média?
Lrkwz
A questão era sobre a função de contagem, não soma ou média. Os dados do Spring ainda não suportam algo como o 'novo caminho' para essas funções. Você poderia usar algo parecido com isto
George Siggouroglou 26/04/2015
1
No seu segundo e terceiro exemplos, acho que você precisaria usar "SELECT COUNT (u) ...", pois essa deveria ser uma consulta de contagem.
TheChrisPratt
Obrigado pelo seu comentário. Foi erro meu.
George Siggouroglou 15/11/2015
Não wrorry, Encontrado o - commons-lang
NickJ
19

Contanto que você não use a versão 1.4, use a anotação explícita:

exemplo:

@Query("select count(e) from Product e where e.area.code = ?1")
long countByAreaCode(String code);
romano
fonte
3
note que o método deve retornar longem vez de int, caso contrário, você receberá uma ClassCastException sem quaisquer pistas
Rangi Lin
13

JpaRepository também estende QueryByExampleExecutor. Portanto, você nem precisa definir métodos personalizados na sua interface:

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

E então consulta como:

User probe = new User();
u.setName = "John";
long count = repo.count(Example.of(probe));
L. Holanda
fonte
Esta versão que eu mais gosto - especialmente porque não consegui entender como isso deve funcionar de acordo com a documentação :-) Você salvou meu dia :-) Como observação: Primitivas (por exemplo, int) estão incluídas na pesquisa de expamle, ou seja int age, será incluído, embora não definido, mas Integer ageserá excluído da amostra (pelo menos no Eclipselink)
LeO
Era exatamente isso que eu estava procurando. Obrigado!
emrekgn
11

Este recurso foi adicionado na versão 1.4 M1

Abel Pastur
fonte
8

Exemplo de trabalho

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

Chamando da camada DAO

@Override
public long countByTenantName(String tenantName) {
    return repository.countByTenantName(tenantName);
}
Sagar Misal
fonte
5

Segundo Abel, após a versão 1.4 (testada na versão 1.4.3.RELEASE) é possível fazer o seguinte:

public long countByName (nome da string);

Marcos Nunes
fonte
2

Obrigado a todos! Agora é trabalho. DATAJPA-231

Seria bom se fosse possível criar count… Por… métodos como encontrar… By ones. Exemplo:

public interface UserRepository extends JpaRepository<User, Long> {

   public Long /*or BigInteger */ countByActiveTrue();
}
Thanongsak Chamung
fonte
1

De acordo com o problema DATAJPA-231, o recurso ainda não foi implementado.

Oleksandr Bondarenko
fonte
Agora está implementado
Sergey Ponomarev
1

Eu trabalho com ele há apenas algumas semanas, mas não acredito que isso seja estritamente possível, mas você poderá obter o mesmo efeito com um pouco mais de esforço; basta escrever a consulta e anotar o nome do método. Provavelmente não é muito mais simples do que escrever o método, mas é mais limpo na minha opinião.

Edit: agora é possível de acordo com DATAJPA-231

Mark Sholund
fonte
0
@Autowired
private UserRepository userRepository;

@RequestMapping("/user/count")
private Long getNumberOfUsers(){
    return userRepository.count();
}
Богдан Ляховецкий
fonte
1
Este exemplo está fora de tópico. O usuário perguntou como countBy nome do campo e não como chamar a contagem básica de um serviço REST.
Jad B.
0

Se alguém quiser obter a contagem com base em várias condições, aqui está uma consulta personalizada de amostra

@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
fonte