Setiap orang yang menggunakan Spring Data menghadapi situasi di mana Anda memiliki repositori untuk bekerja dengan suatu entitas dan Anda ingin menulis metode pencarian universal untuk mencari dengan seperangkat parameter yang dapat ditetapkan atau dilewati pengguna pada formulir pencarian. Implementasi dasar metode find di Spring Data menemukan entitas hanya dengan mempertimbangkan semua parameter, tidak memungkinkan Anda untuk mencari dengan set yang terbatas. Saya menemukan cara untuk mengatasi masalah ini dan membuat perpustakaan OpenSource untuk penggunaan cepat dalam proyek lain.
Untuk memahami masalah, mari kita bayangkan bahwa kita sedang membuat aplikasi notebook sederhana, di mana kita mendefinisikan entitas - Orang dengan id bidang, firstName, lastName, phoneNumber.
Person.java@Entity @Data @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode(of = "id") public class Person { @Id private Long id; private String firstName; private String lastName; private String phoneNumber; }
Misalkan kita harus menyediakan pencarian berdasarkan nama depan, nama belakang dan bagian dari nomor telepon atau dengan kombinasi dari parameter-parameter ini dan ingin metode pencarian tidak memperhitungkan parameter akun yang nilainya nol. Untuk mengatasi masalah ini, Anda dapat melakukan beberapa cara:
- Bekerja secara langsung dengan database melalui SQL, buat metode dalam layanan yang secara dinamis akan menghasilkan query SQL. Sesuatu seperti
Kueri dinamis Iterable<Person> find(String firstName, String lastName, String phoneNumber) { List<String> where = new ArrayList(); List params = new ArrayList(); if(firstName != null) { params.add(firstName); where.add("first_name = ?"); } if(lastName != null) { params.add(lastName); where.add("last_name = ?"); } if(phoneNumber != null) { params.add(phoneNumber); where.add("phone_number = ?"); } String sql = "SELECT * FROM person " + (where.isEmpty() ? "" : " WHERE " + String.join(" AND ", where));
- Gunakan anotasi Permintaan untuk metode pencarian dengan parameter memeriksa null.
@Query @Query("SELECT p FROM Person p " + "WHERE " + "(firstName = :firstName or :firstName is null) and " + "(lastName = :lastName or :lastName is null) and " + "(phoneNumber = :phoneNumber or :phoneNumber is null)" ) Iterable<Person> find( @Param("firstName") String firstName, @Param("lastName") String lastName, @Param("phoneNumber") String phoneNumber );
- Buat metode pencarian untuk semua kemungkinan kombinasi parameter dan panggil metode yang diinginkan setelah memeriksa parameter untuk null.
Banyak metode menemukan @Repository public interface PersonRepo extends PagingAndSortingRepository<Person, Long> {
Saya tidak akan menganalisis kelebihan dan kekurangan masing-masing metode, mereka jelas. Saya hanya bisa mengatakan bahwa saya memilih opsi ketiga dengan penambahan metode pencarian untuk setiap varian kombinasi parameter dan membuat perpustakaan OpenSource yang menggunakan mekanisme Prosesor Anotasi dan pada tahap kompilasi melakukan semua pekerjaan untuk Anda. Untuk menggunakannya, Anda harus menghubungkan perpustakaan (lihat versi terbaru di
https://github.com/ukman/kolobok atau
https://mvnrepository.com/artifact/com.github.ukman/kolobok ).
<dependency> <groupId>com.github.ukman</groupId> <artifactId>kolobok</artifactId> <version>0.1.2</version> <scope>compile</scope> </dependency>
Maka Anda perlu menandai metode ini, yang seharusnya bekerja dengan cara baru dengan penjelasan @FindWithOptionalParams.
@Repository public interface PersonRepo extends PagingAndSortingRepository<Person, Long> { @FindWithOptionalParams Iterable<Person> findByFirstNameAndLastNameAndPhoneNumberContains(String firstName, String lastName, String number); }
Perpustakaan itu sendiri akan menghasilkan semua metode pencarian dan implementasi default dengan memeriksa parameter untuk null dan memanggil metode yang diperlukan.
PS: tulis di komentar apa penjelasan lain dapat menyederhanakan pekerjaan Anda dengan Spring, mungkin saya akan menambahkannya juga.