Spring CrudRepository findByInventoryIds (List <Long> InventoryIdList) - odpowiednik klauzuli IN

169

Czy w Spring CrudRepository obsługujemy „klauzulę IN” dla pola? tj. coś podobnego do następującego?

 findByInventoryIds(List<Long> inventoryIdList) 

Jeśli takie wsparcie nie jest dostępne, jakie eleganckie opcje można rozważyć? Wykonywanie zapytań dla każdego identyfikatora może nie być optymalne.

Espresso
źródło

Odpowiedzi:

283

findByInventoryIdIn(List<Long> inventoryIdList) powinien załatwić sprawę.

Format parametru żądania HTTP wyglądałby następująco:

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

Pełną listę słów kluczowych repozytorium JPA można znaleźć w aktualnej liście dokumentacji . Pokazuje, że IsInjest to równoważne - jeśli wolisz czasownik dla czytelności - i że JPA obsługuje również NotIni IsNotIn.

Oliver Drotbohm
źródło
Dzięki, właśnie tego szukałem. Czy mają to udokumentowane na stronie CrudRepository, czy odkrywają, czytając kod?
Espresso
1
W rzeczywistości jest wymieniony w dokumentacji referencyjnej .
Oliver Drotbohm
Dzięki. Ten "klejnot jest ukryty w dodatku B", słusznie :)
Espresso
11
Adres URL dokumentów referencyjnych został zmieniony
Mayjak,
1
Dla podpisu metody: List <Person> findByIdIn (List <Integer> ids);
Pojawia
103

Dla każdej metody w Spring CrudRepository powinieneś być w stanie samodzielnie określić @Query. Coś takiego powinno działać:

@Query( "select o from MyObject o where inventoryId in :ids" )
List<MyObject> findByInventoryIds(@Param("ids") List<Long> inventoryIdList);
digitaljoel
źródło
Dzięki, to działa. Szukałem „bardziej przejrzystego” rozwiązania, tj. Bez pisania @Query.
Espresso
3
Oliver Gierke jest człowiekiem, który znałby odpowiedź na to pytanie i ma „czystsze” rozwiązanie. Powinieneś przyjąć jego odpowiedź.
digitaljoel,
1
Wspaniały! Użyłem Set<String>jako parametru, działało dobrze.
BlueBird
co, jeśli chcę przekazać 2 parametry do mojej metody, jedną listę, a drugą zwykły ciąg, czy to zadziała? jeśli tak, jak mam nazwać swoją metodę
user3614936
22

Tak, to jest obsługiwane.

Sprawdź dokumentację tutaj, aby znaleźć obsługiwane słowa kluczowe w nazwach metod.

Możesz po prostu zdefiniować metodę w interfejsie repozytorium bez używania adnotacji @Query i pisania niestandardowego zapytania. W twoim przypadku wyglądałoby to następująco:

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

Zakładam, że masz jednostkę Inventory i interfejs InventoryRepository . Kod w Twoim przypadku powinien wyglądać następująco:

Jednostka

@Entity
public class Inventory implements Serializable {

  private static final long serialVersionUID = 1L;

  private Long id;

  // other fields
  // getters/setters

}

Repozytorium

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

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

}
Dzinot
źródło
Działa to dla wszystkich interfejsów, które rozszerzają interfejs CrudRepository .
Dzinot
1
To nie zadziała, jeśli rozmiar identyfikatorów przekracza 1000 lub określony rozmiar w zależności od bazy danych. Co powiesz na to? List <Inventory> findByIdIn (Identyfikatory listy <Long>, możliwe do stronicowania);
Julie