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.


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 .


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);

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));

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


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);
}

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);



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();
}


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


0
@Autowired
private UserRepository userRepository;

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

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);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.