Spring CrudRepository findByInventoryIds (List <Long> inventarIdList) - entspricht der IN-Klausel

169

Haben wir in Spring CrudRepository Unterstützung für die "IN-Klausel" für ein Feld? dh etwas ähnliches wie das folgende?

 findByInventoryIds(List<Long> inventoryIdList) 

Welche eleganten Optionen können in Betracht gezogen werden, wenn eine solche Unterstützung nicht verfügbar ist? Das Auslösen von Abfragen für jede ID ist möglicherweise nicht optimal.

Espresso
quelle

Antworten:

283

findByInventoryIdIn(List<Long> inventoryIdList) sollte den Trick machen.

Das HTTP-Anforderungsparameterformat sieht folgendermaßen aus:

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

Die vollständige Liste der JPA-Repository-Schlüsselwörter finden Sie in der aktuellen Dokumentationsliste . Es zeigt, dass dies IsInäquivalent ist - wenn Sie das Verb für die Lesbarkeit bevorzugen - und dass JPA auch NotInund unterstützt IsNotIn.

Oliver Drotbohm
quelle
Danke, genau das habe ich gesucht. Haben sie es auf der CrudRepository-Seite dokumentiert oder durch Lesen des Codes entdeckt?
Espresso
1
Es ist tatsächlich in der Referenzdokumentation aufgeführt .
Oliver Drotbohm
Vielen Dank. Das "Juwel ist im Anhang B versteckt", zu Recht :)
Espresso
11
URL der Referenzdokumente geändert
Mayjak
1
Für die Methodensignatur: List <Person> findByIdIn (List <Integer> ids); Ich erhalte die Fehlermeldung: Auslöser: java.lang.NumberFormatException: Für Eingabezeichenfolge: "(1, 2)"
user64141
103

Für jede Methode in einem Spring CrudRepository sollten Sie in der Lage sein, die @Query selbst anzugeben. So etwas sollte funktionieren:

@Query( "select o from MyObject o where inventoryId in :ids" )
List<MyObject> findByInventoryIds(@Param("ids") List<Long> inventoryIdList);
digitaljoel
quelle
Danke, das funktioniert. War auf der Suche nach einer "saubereren" Lösung, dh ohne die @Query zu schreiben.
Espresso
3
Oliver Gierke ist der Mann, der die Antwort darauf wissen würde, und er hat die "sauberere" Lösung. Sie sollten seine Antwort akzeptieren.
Digitaljoel
1
Toll! Ich habe a Set<String>als Parameter verwendet, hat gut funktioniert.
BlueBird
Was passiert, wenn ich meiner Methode 2 Parameter, eine Liste und eine normale Zeichenfolge, übergeben möchte? Wenn ja, wie soll ich meine Methode
benennen
22

Ja, das wird unterstützt.

In der hier bereitgestellten Dokumentation finden Sie die unterstützten Schlüsselwörter in den Methodennamen.

Sie können die Methode einfach in der Repository-Oberfläche definieren, ohne die Annotation @Query zu verwenden und Ihre benutzerdefinierte Abfrage zu schreiben. In Ihrem Fall wäre es wie folgt:

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

Ich gehe davon aus, dass Sie die Inventory- Entität und die InventoryRepository- Schnittstelle haben. Der Code in Ihrem Fall sollte folgendermaßen aussehen:

Die Entität

@Entity
public class Inventory implements Serializable {

  private static final long serialVersionUID = 1L;

  private Long id;

  // other fields
  // getters/setters

}

Das Repository

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

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

}
Dzinot
quelle
Dies funktioniert für alle Schnittstellen, die die CrudRepository- Schnittstelle erweitern.
Dzinot
1
Dies funktioniert nicht, wenn die ID-Größe über 1000 oder eine bestimmte Größe liegt, abhängig von der Datenbank. Wie wäre es damit? List <Inventory> findByIdIn (List <Long> ids, Pageable pageable);
Julie