¿Spring Data JPA tiene alguna forma de contar las entidades utilizando la resolución de nombre de método?


125

Spring Data JPA admite entidades de recuento que utilizan especificaciones. Pero, ¿tiene alguna forma de contar entidades usando la resolución de nombres de métodos? Digamos que quiero un método countByNamepara contar entidades con un nombre específico, al igual que un método findByNamepara obtener todas las entidades con un nombre específico.


66
Acepta una de las respuestas, YaoFeng. He probado Spring Data JPA 1.5.2 y la sintaxis countByName () funciona como notas de Abel.
nullPainter

Respuestas:


214

A partir de Spring Data 1.7.1.RELEASE , puede hacerlo de dos maneras diferentes,

1) La nueva forma , utilizando derivación de consultas para contar y eliminar consultas. Lea esto (Ejemplo 5). Ejemplo,

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

2) A la antigua usanza , utilizando la anotación @Query.
Ejemplo,

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

o usando la anotación @Param también,

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

Comprueba también esto, así que responde .


3
¿Qué pasa con otras funciones agregadas como suma, promedio?
lrkwz

La pregunta era sobre la función de conteo, no suma o promedio. Los datos de Spring todavía no admiten algo como la 'nueva forma' para estas funciones. Podría usar algo como esto
George Siggouroglou

1
En su segundo y tercer ejemplo, creo que necesitaría usar "SELECT COUNT (u) ...", ya que se supone que es una consulta de conteo.
TheChrisPratt

Gracias por tu comentario. Fue mi error.
George Siggouroglou

No para wrorry, lo encontré - commons-lang
NickJ

19

Mientras no use la versión 1.4, puede usar anotaciones explícitas:

ejemplo:

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

3
tenga en cuenta que el método debería regresar en longlugar de int, de lo contrario obtendrá una ClassCastException sin ninguna pista
Rangi Lin

13

JpaRepository también extiende QueryByExampleExecutor. Por lo tanto, ni siquiera necesita definir métodos personalizados en su interfaz:

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

Y luego consulta como:

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

Esta versión me gusta más, especialmente porque no pude dar una idea de cómo debería funcionar según el docu :-) Me salvaste el día :-) Como comentario: Primitivas (por ejemplo, int) están incluidas en la búsqueda de expamle, es decir int age, se incluirá aunque no esté configurado, pero Integer agese excluirá de la muestra (al menos en Eclipselink)
LeO

Esto es exactamente lo que estaba buscando. ¡Gracias!
emrekgn


8

Ejemplo de trabajo

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

Llamando desde la capa DAO

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

5

Según Abel, después de la versión 1.4 (probada en la versión 1.4.3.RELEASE) es posible hacerlo de esta manera:

public long countByName (nombre de cadena);



2

¡Gracias a todos! Ahora es trabajo. DATAJPA-231

Sería bueno si fuera posible crear conteo ... Por ... métodos como encontrar ... Por unos. Ejemplo:

public interface UserRepository extends JpaRepository<User, Long> {

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


1

Solo he estado trabajando con él durante algunas semanas, pero no creo que esto sea estrictamente posible, sin embargo, debería poder obtener el mismo efecto con un poco más de esfuerzo; solo escriba la consulta usted mismo y anote el nombre del método. Probablemente no sea mucho más simple que escribir el método usted mismo, pero en mi opinión es más limpio.

Editar: ahora es posible de acuerdo con DATAJPA-231


0
@Autowired
private UserRepository userRepository;

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

1
Este ejemplo está fuera de tema. El usuario preguntó cómo contar por nombre de campo y no cómo llamar al conteo básico desde un servicio REST.
Jad B.

0

Si alguien quiere obtener el recuento basado en múltiples condiciones, aquí hay una consulta personalizada de muestra

@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);
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.