Spring CrudRepository findByInventoryIds (List <Long> InventoryIdList) - équivalent à la clause IN

170

Dans Spring CrudRepository, avons-nous le support de la "clause IN" pour un champ? c'est-à-dire quelque chose de similaire à ce qui suit?

 findByInventoryIds(List<Long> inventoryIdList) 

Si un tel support n'est pas disponible, quelles options élégantes peuvent être envisagées? Le déclenchement de requêtes pour chaque identifiant peut ne pas être optimal.

Expresso
la source

Réponses:

284

findByInventoryIdIn(List<Long> inventoryIdList) devrait faire l'affaire.

Le format du paramètre de requête HTTP serait comme ceci:

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

La liste complète des mots-clés du référentiel JPA se trouve dans la liste actuelle de la documentation . Cela montre que IsInc'est équivalent - si vous préférez le verbe pour la lisibilité - et que JPA prend également en charge NotInet IsNotIn.

Oliver Drotbohm
la source
Merci, c'était exactement ce que je cherchais. Est-ce qu'ils l'ont documenté dans la page CrudRepository, ou découvert en lisant le code?
Espresso du
1
Il est en fait répertorié dans la documentation de référence .
Oliver Drotbohm le
Merci. Ce "joyau est caché dans l'annexe B", à juste titre :)
Espresso
11
L' URL de la documentation de référence a été modifiée
Mayjak
1
Pour la signature de méthode: List <Person> findByIdIn (List <Integer> ids); J'obtiens l'erreur: Causée par: java.lang.NumberFormatException: Pour la chaîne d'entrée: "(1, 2)"
user64141
103

Pour toute méthode dans un Spring CrudRepository, vous devriez être en mesure de spécifier vous-même @Query. Quelque chose comme ça devrait fonctionner:

@Query( "select o from MyObject o where inventoryId in :ids" )
List<MyObject> findByInventoryIds(@Param("ids") List<Long> inventoryIdList);
digitaljoel
la source
Merci, cela fonctionne. Cherchait une solution "plus propre" c'est à dire sans écrire la @Query.
Espresso
3
Oliver Gierke est l'homme qui connaîtrait la réponse à cela et il a la solution «plus propre». Vous devriez accepter sa réponse.
digitaljoel
1
Génial! J'ai utilisé un Set<String>paramètre, a bien fonctionné.
BlueBird
et si je veux passer 2 paramètres à ma méthode une liste et à l'autre une chaîne normale, cela fonctionnera-t-il? si oui, comment nommer ma méthode
user3614936
22

Oui, cela est pris en charge.

Consultez la documentation fournie ici pour les mots-clés pris en charge dans les noms de méthode.

Vous pouvez simplement définir la méthode dans l'interface du référentiel sans utiliser l' annotation @Query et écrire votre requête personnalisée. Dans votre cas, ce serait comme suit:

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

Je suppose que vous avez l' entité Inventory et l' interface InventoryRepository . Le code dans votre cas devrait ressembler à ceci:

L'entité

@Entity
public class Inventory implements Serializable {

  private static final long serialVersionUID = 1L;

  private Long id;

  // other fields
  // getters/setters

}

Le référentiel

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

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

}
Dzinot
la source
Cela fonctionne pour toutes les interfaces qui étendent l' interface CrudRepository .
Dzinot
1
Cela ne fonctionnera pas si la taille des identifiants est supérieure à 1000 ou à une certaine taille selon la base de données. Que dis-tu de ça? List <Inventory> findByIdIn (List <Long> ids, Pageable pageable);
Julie