Spring CrudRepository findByInventoryIds (Daftar <Long> inventoryIdList) - setara dengan klausa IN

169

Di Spring CrudRepository, apakah kita memiliki dukungan untuk "IN clause" untuk sebuah bidang? yaitu sesuatu yang mirip dengan yang berikut ini?

 findByInventoryIds(List<Long> inventoryIdList) 

Jika dukungan semacam itu tidak tersedia, opsi elegan apa yang dapat dipertimbangkan? Memecat kueri untuk setiap id mungkin tidak optimal.

espreso
sumber

Jawaban:

283

findByInventoryIdIn(List<Long> inventoryIdList) harus melakukan trik.

Format parameter permintaan HTTP akan seperti ini:

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

Daftar lengkap kata kunci repositori JPA dapat ditemukan di daftar dokumentasi saat ini . Ini menunjukkan bahwa IsInitu setara - jika Anda lebih suka kata kerja untuk keterbacaan - dan JPA juga mendukung NotIndan IsNotIn.

Oliver Drotbohm
sumber
Terima kasih, itulah tepatnya yang saya cari. Apakah mereka mendokumentasikannya di halaman CrudRepository, atau menemukan dengan membaca kode?
Espresso
1
Ini sebenarnya tercantum dalam dokumentasi referensi .
Oliver Drotbohm
Terima kasih. "Permata itu tersembunyi di apendiks B", memang demikian :)
Espresso
11
URL dokumen rujukan diubah
Mayjak
1
Untuk tanda tangan metode: Daftar <Person> findByIdIn (Cantumkan <Integer> id); Saya mendapatkan kesalahan: Disebabkan oleh: java.lang.NumberFormatException: Untuk string input: "(1, 2)"
user64141
103

Untuk metode apa pun di Spring CrudRepository, Anda harus dapat menentukan sendiri @Query. Sesuatu seperti ini seharusnya bekerja:

@Query( "select o from MyObject o where inventoryId in :ids" )
List<MyObject> findByInventoryIds(@Param("ids") List<Long> inventoryIdList);
digitaljoel
sumber
Terima kasih, ini berhasil. Sedang mencari solusi "lebih bersih" yaitu tanpa menulis @Query.
Espresso
3
Oliver Gierke adalah orang yang tahu jawabannya dan dia punya solusi "lebih bersih". Anda harus menerima jawabannya.
digitaljoel
1
Bagus! Saya menggunakan Set<String>sebagai parameter, bekerja dengan baik.
BlueBird
bagaimana jika saya ingin melewatkan 2 parameter ke metode saya satu daftar dan lainnya string normal, apakah itu akan berfungsi? jika ya bagaimana saya akan memberi nama metode saya
user3614936
22

Ya, itu didukung.

Periksa dokumentasi yang disediakan di sini untuk kata kunci yang didukung di dalam nama metode.

Anda bisa mendefinisikan metode di antarmuka repositori tanpa menggunakan anotasi @Query dan menulis kueri khusus Anda. Dalam kasus Anda itu akan sebagai berikut:

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

Saya berasumsi bahwa Anda memiliki entitas Inventaris dan antarmuka InventoryRepository . Kode dalam kasus Anda akan terlihat seperti ini:

Entitas

@Entity
public class Inventory implements Serializable {

  private static final long serialVersionUID = 1L;

  private Long id;

  // other fields
  // getters/setters

}

Repositori

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

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

}
Dzinot
sumber
Ini berfungsi untuk semua antarmuka yang memperluas antarmuka CrudRepository .
Dzinot
1
Ini tidak akan berfungsi jika ukuran id lebih dari 1000 atau ukuran tertentu tergantung pada DB. Bagaimana dengan ini? List <Inventory> findByIdIn (Daftar id <Long>, pageable pageable);
Julie