Spring CrudRepository findByInventoryIds (List <Long> inventIdList) - equivalente à cláusula IN

169

No Spring CrudRepository, temos suporte para a "cláusula IN" de um campo? ou seja, algo semelhante ao seguinte?

 findByInventoryIds(List<Long> inventoryIdList) 

Se esse suporte não estiver disponível, que opções elegantes podem ser consideradas? As consultas de acionamento para cada ID podem não ser ideais.

Espresso
fonte

Respostas:

283

findByInventoryIdIn(List<Long> inventoryIdList) deve fazer o truque.

O formato do parâmetro de solicitação HTTP seria assim:

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

A lista completa de palavras-chave do repositório JPA pode ser encontrada na lista de documentação atual . Mostra que IsIné equivalente - se você preferir o verbo para legibilidade - e que o JPA também suporta NotIne IsNotIn.

Oliver Drotbohm
fonte
Obrigado, era exatamente isso que eu estava procurando. Eles o documentam na página CrudRepository ou descobrem lendo o código?
Espresso
1
Na verdade, está listado na documentação de referência .
Oliver Drotbohm 27/09/2013
Obrigado. Que "jóia está escondido no apêndice B", com razão :)
Espresso
11
URL dos documentos de referência alterado
Mayjak
1
Para a assinatura do método: List <Person> findByIdIn (List <Integer> ids); Eu recebo o erro: Causado por: java.lang.NumberFormatException: For string de entrada: "(1, 2)"
user64141
103

Para qualquer método em um Spring CrudRepository, você deve especificar o @Query por conta própria. Algo assim deve funcionar:

@Query( "select o from MyObject o where inventoryId in :ids" )
List<MyObject> findByInventoryIds(@Param("ids") List<Long> inventoryIdList);
digitaljoel
fonte
Obrigado, isso funciona. Estava procurando uma solução "mais limpa", ou seja, sem escrever o @Query.
Espresso
3
Oliver Gierke é o homem que saberia a resposta para isso e ele tem a solução "mais limpa". Você deve aceitar a resposta dele.
Digitaljoel 25/09/13
1
Ótimo! Eu usei a Set<String>como parâmetro, funcionou bem.
BlueBird
e se eu quiser passar 2 parâmetros para o meu método, uma lista e outra uma string normal, isso funcionará? se sim como eu nomearei meu método
user3614936
22

Sim, isso é suportado.

Verifique a documentação fornecida aqui para as palavras-chave suportadas nos nomes dos métodos.

Você pode apenas definir o método na interface do repositório sem usar a anotação @Query e escrever sua consulta personalizada. No seu caso, seria o seguinte:

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

Presumo que você tenha a entidade Inventory e a interface InventoryRepository . O código no seu caso deve ficar assim:

A entidade

@Entity
public class Inventory implements Serializable {

  private static final long serialVersionUID = 1L;

  private Long id;

  // other fields
  // getters/setters

}

O Repositório

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

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

}
Dzinot
fonte
Isso funciona para todas as interfaces que estão estendendo a interface CrudRepository .
Dzinot 11/11
1
Isso não funcionará se o tamanho dos IDs for maior que 1000 ou certo tamanho, dependendo do banco de dados. Que tal agora? List <Inventory> findByIdIn (List <Long> ids, Pageable paginável);
Julie