Spring CrudRepository findByInventoryIds (List <Long> InventoryIdList) - equivalente a la cláusula IN


169

En Spring CrudRepository, ¿tenemos soporte para la "cláusula IN" para un campo? es decir, algo similar a lo siguiente?

 findByInventoryIds(List<Long> inventoryIdList) 

Si dicho soporte no está disponible, ¿qué opciones elegantes se pueden considerar? Las consultas de disparo para cada ID pueden no ser óptimas.

Respuestas:


283

findByInventoryIdIn(List<Long> inventoryIdList) debería hacer el truco.

El formato del parámetro de solicitud HTTP sería así:

Yes ?id=1,2,3
No  ?id=1&id=2&id=3

La lista completa de palabras clave del repositorio JPA se puede encontrar en la lista de documentación actual . Muestra que IsInes equivalente, si prefiere el verbo legibilidad, y que JPA también admite NotIny IsNotIn.


Gracias, eso era exactamente lo que estaba buscando. ¿Lo tienen documentado en la página CrudRepository o lo descubren leyendo el código?
Espresso

1
En realidad, se enumera en la documentación de referencia .
Oliver Drotbohm

Gracias. Esa "joya está escondida en el apéndice B", con razón :)
Espresso

11
URL de documentos de referencia modificada
Mayjak

1
Para la firma del método: List <Person> findByIdIn (List <Integer> ids); Me sale el error: Causado por: java.lang.NumberFormatException: Para la cadena de entrada: "(1, 2)"
user64141

103

Para cualquier método en un Spring CrudRepository, debería poder especificar el @Query usted mismo. Algo como esto debería funcionar:

@Query( "select o from MyObject o where inventoryId in :ids" )
List<MyObject> findByInventoryIds(@Param("ids") List<Long> inventoryIdList);

Gracias, esto funciona. Estaba buscando una solución "más limpia", es decir, sin escribir el @Query.
Espresso

3
Oliver Gierke es el hombre que sabría la respuesta a esto y tiene la solución "más limpia". Deberías aceptar su respuesta.
digitaljoel

1
¡Excelente! Utilicé a Set<String>como parámetro, funcionó bien.
BlueBird

¿Qué pasa si quiero pasar 2 parámetros a mi método, una lista y otra una cadena normal, funcionará? en caso afirmativo, ¿cómo
nombraré

22

Sí, eso es compatible.

Consulte la documentación proporcionada aquí para las palabras clave compatibles dentro de los nombres de los métodos.

Simplemente puede definir el método en la interfaz del repositorio sin usar la anotación @Query y escribir su consulta personalizada. En su caso, sería como sigue:

List<Inventory> findByIdIn(List<Long> ids);

Supongo que tiene la entidad Inventory y la interfaz InventoryRepository . El código en su caso debería verse así:

La entidad

@Entity
public class Inventory implements Serializable {

  private static final long serialVersionUID = 1L;

  private Long id;

  // other fields
  // getters/setters

}

El repositorio

@Repository
@Transactional
public interface InventoryRepository extends PagingAndSortingRepository<Inventory, Long> {

  List<Inventory> findByIdIn(List<Long> ids);

}

Esto funciona para todas las interfaces que amplían la interfaz CrudRepository .
Dzinot

1
Esto no funcionará si el tamaño de los ID es superior a 1000 o cierto tamaño dependiendo de la base de datos. ¿Qué tal esto? List <Inventory> findByIdIn (List <Long> ids, Pageable pageable);
Julie
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.