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.

Café exprés
fuente

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.

Oliver Drotbohm
fuente
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);
digitaljoel
fuente
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);

}
Dzinot
fuente
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