स्प्रिंग डेटा का उपयोग करने वाले सभी लोगों को एक ऐसी स्थिति का सामना करना पड़ा जहां आपके पास एक इकाई के साथ काम करने के लिए एक भंडार है और आप एक सार्वभौमिक खोज विधि लिखना चाहते हैं जो मापदंडों के एक सेट द्वारा खोज करने के लिए है जिसे उपयोगकर्ता खोज फ़ॉर्म पर सेट या छोड़ सकता है। स्प्रिंग डेटा में तरीकों को खोजने का मूल कार्यान्वयन केवल सभी मापदंडों को ध्यान में रखते हुए इकाइयां पाता है, न कि आपको एक सीमित सेट द्वारा खोजने की अनुमति देता है। मुझे इस समस्या को हल करने का एक तरीका मिला और अन्य परियोजनाओं में त्वरित उपयोग के लिए एक ओपनसोर्स लाइब्रेरी बनाई।
समस्याओं को समझने के लिए, आइए कल्पना करें कि हम एक साधारण नोटबुक एप्लिकेशन बना रहे हैं जिसमें हम एक इकाई को परिभाषित करते हैं - पर्सन विद द फील्ड आईडी, फर्स्टनाम, लास्टनेम, फोननंबर।
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; }
मान लें कि हमें पहले नाम, अंतिम नाम और टेलीफोन नंबर के किसी भाग या इन मापदंडों के संयोजन से खोज प्रदान करनी चाहिए और चाहते हैं कि खोज विधि उन मापदंडों को ध्यान में न रखे, जिनके मूल्य शून्य हैं। इस समस्या को हल करने के लिए, आप कई तरीकों से जा सकते हैं:
- SQL के माध्यम से डेटाबेस के साथ सीधे काम करें, सेवा में एक विधि बनाएं जो गतिशील रूप से SQL क्वेरी उत्पन्न करेगा। कुछ इस तरह
गतिशील क्वेरी 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));
- अशक्त के लिए पैरामीटर जाँच के साथ एक खोज विधि के लिए क्वेरी एनोटेशन का उपयोग करें।
@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 );
- मापदंडों के सभी संभावित संयोजनों के लिए खोज विधियां बनाएं और अशक्त के लिए मापदंडों की जांच के बाद वांछित विधि को कॉल करें।
बहुत सारे तरीके खोजे @Repository public interface PersonRepo extends PagingAndSortingRepository<Person, Long> {
मैं प्रत्येक विधि के फायदे और नुकसान का विश्लेषण नहीं करूंगा, वे स्पष्ट हैं। मैं केवल यह कह सकता हूं कि मैंने मापदंडों के प्रत्येक विकल्प संयोजन के लिए खोज विधियों को जोड़ने के साथ तीसरा विकल्प चुना और एक OpenSource पुस्तकालय बनाया जो एनोटेशन प्रोसेसर तंत्र का उपयोग करता है और संकलन चरण में आपके लिए सभी काम करता है। इसका उपयोग करने के लिए, आपको लाइब्रेरी को कनेक्ट करना होगा (
https://github.com/ukman/kolobok या
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>
फिर आपको विधि को चिह्नित करने की आवश्यकता है, जो एनोटेशन @FindWithOptionalParams के साथ एक नए तरीके से काम करना चाहिए।
@Repository public interface PersonRepo extends PagingAndSortingRepository<Person, Long> { @FindWithOptionalParams Iterable<Person> findByFirstNameAndLastNameAndPhoneNumberContains(String firstName, String lastName, String number); }
पुस्तकालय स्वयं सभी खोज विधियों और डिफ़ॉल्ट कार्यान्वयन को शून्य के लिए मापदंडों की जांच करने और आवश्यक विधि को कॉल करने के साथ उत्पन्न करेगा।
पुनश्च: टिप्पणियों में लिखें कि अन्य एनोटेशन स्प्रिंग के साथ आपके काम को सरल बना सकते हैं, शायद मैं उन्हें भी जोड़ दूंगा।