¿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.

YaoFeng
fuente
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 .

George Siggouroglou
fuente
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);
romano
fuente
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));
L. Holanda
fuente
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
11

Esta característica se ha agregado en la versión 1.4 M1

Abel Pastur
fuente
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);
}
Sagar Misal
fuente
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);

Marcos Nunes
fuente
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();
}
Thanongsak Chamung
fuente
1

Según el problema DATAJPA-231, la función aún no está implementada.

Oleksandr Bondarenko
fuente
Ahora está implementado
Sergey Ponomarev
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

Mark Sholund
fuente
0
@Autowired
private UserRepository userRepository;

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