2012-05-29 15 views
22

स्प्रिंग डेटा जेपीए क्वेरी घोषित करने का सबसे आसान तरीका क्या है जो क्वेरी पैरामीटर के रूप में इनपुट पैरामीटर के गुणों का उपयोग करता है?पैरामीटर गुणों के साथ वसंत डेटा जेपीए क्वेरी

उदाहरण के लिए, मैं एक इकाई वर्ग है:

public class Person { 
    @Id 
    private long id; 

    @Column 
    private String forename; 

    @Column 
    private String surname; 
} 

और एक अन्य वर्ग:

public class Name { 
    private String forename; 
    private String surname; 

    [constructor and getters] 
} 

... तो मैं इस प्रकार एक स्प्रिंग डाटा भंडार लिखने के लिए करना चाहते हैं:

public interface PersonRepository extends CrudRepository<Person, Long> { 
    @Query("select p from Person p where p.forename = ?1.forename and p.surname = ?1.surname") 
    findByName(Name name); 
} 

... लेकिन वसंत डेटा/जेपीए मुझेपर संपत्ति के नाम निर्दिष्ट नहीं करना पसंद नहीं करतापैरामीटर।

सबसे अच्छा विकल्प क्या है? }

+0

यह गतिशील होना चाहिए? आप कथन के बाद 'नाम' तालिका क्यों नहीं जोड़ सकते हैं? –

+0

'नाम' आवश्यक रूप से एक इकाई नहीं है। – Kkkev

उत्तर

46

इस लिंक से आपको मदद मिलेगी: समर्थित स्पेल भाव के साथ स्प्रिंग डाटा जेपीए एम 1। समान उदाहरण होगा:

@Query("select u from User u where u.firstname = :#{#customer.firstname}") 
List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer); 

https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions

+0

यह वसंत-डेटा-जेपीए 1.7.2 + है और वसंत 4 – chrismarx

+0

ग्राहक को यहां एक इकाई होना प्रतीत होता है, पीओजेओ का मूल्यांकन मेरे लिए काम नहीं करता है। – Schaka

+0

एक pojo के साथ कोशिश नहीं की है, मैं पुष्टि कर सकता हूँ कि यह कम से कम इकाइयों के साथ काम कर रहा है। किसी और ने उल्लेख किया था कि यदि वे किसी ऑब्जेक्ट और अतिरिक्त तर्क (यहां टिप्पणियां देखें) शामिल हैं तो वे समस्याओं में भाग गए हैं - https://spring.io/blog/2014/07/15/spel-support-in-spring- डेटा-जेपीए-प्रश्न-परिभाषाओं – chrismarx

10

जो आप चाहते हैं वह संभव नहीं है। आपको दो पैरामीटर बनाना होगा, और उन्हें अलग से बांधना होगा:

select p from Person p where p.forename = :forename and p.surname = :surname 
... 
query.setParameter("forename", name.getForename()); 
query.setParameter("surname", name.getSurname()); 
+1

मुमकिन है इस http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/#repositories.single-repository-behaviour के अनुसार एक कस्टम भंडार विधि में लागू करने की आवश्यकता होगी? – Kkkev

+1

मुझे पता है कि जेपीए कैसे काम करता है, लेकिन मुझे नहीं पता कि वसंत-डेटा आपके लिए क्या करता है और आपको अपने आप क्या करना चाहिए। माफ़ कीजिये। –

16

निम्नानुसार हस्ताक्षर के साथ क्वेरी विधि को परिभाषित करें।

@Query(select p from Person p where p.forename = :forename and p.surname = :surname) 
User findByForenameAndSurname(@Param("surname") String lastname, 
          @Param("forename") String firstname); 
} 

अधिक जानकारी के लिए, जाँच the Spring Data JPA reference

+1

वह सवाल का जवाब नहीं देता है। प्रासंगिक बिंदु यह है कि मैं क्वेरी पैरामीटर के रूप में इनपुट पैरामीटर के गुणों का उपयोग करना चाहता हूं, इनपुट इनपुट पैरामीटर नहीं। – Kkkev

+0

ओह, मैं आपकी क्वेरी को गलत पढ़ता हूं। मेरा मानना ​​है कि समर्थन स्प्रिंग डेटा जेपीए द्वारा प्रदान नहीं किया गया है (शायद यहां तक ​​कि जेडीबीसी भी नहीं हो सकता है; मैं यहां गलत हो सकता हूं)। एक और विकल्प (कस्टम भंडार दृष्टिकोण से अलग) के रूप में, आप एक सेवा आवरण विधि पैरामीटर के रूप में व्यक्ति वस्तु लेता है लिख सकते हैं और भंडार विधि से संबंधित मानकों को पारित कर सकते हैं। इस दृष्टिकोण के साथ लाभ यह है कि आपके द्वारा अपेक्षित हस्ताक्षर (पास ऑब्जेक्ट पास) बरकरार है और आप स्प्रिंग डेटा जेपीए द्वारा प्रदान किए गए कार्यान्वयन का भी उपयोग करते हैं। –

5

आप कुछ इस तरह की कोशिश कर सकते हैं:

public interface PersonRepository extends CrudRepository<Person, Long> { 
     @Query("select p from Person AS p" 
     + " ,Name AS n" 
     + " where p.forename = n.forename " 
     + " and p.surname = n.surname" 
     + " and n = :name") 
     Set<Person>findByName(@Param("name") Name name); 
    } 
+1

नाम एक इकाई नहीं है, इसलिए यह काम नहीं करता है। – Kkkev

+0

@Kkkev सही है, आपको इस समाधान के लिए नाम एक इकाई बनाना होगा – Casi

1

आप एक @Service भी साथ काम कर रहे हैं? यदि आप कर रहे हैं, तो आप अपने PersonRepository@Service के लिए और फिर सेवा में @Autowired कर सकते हैं क्योंकि अभी Name वर्ग आह्वान और रूप है कि @CuriosMind ... प्रस्तावित का उपयोग करें:

@Query(select p from Person p where p.forename = :forename and p.surname = :surname) 
User findByForenameAndSurname(@Param("surname") String lastname, 
         @Param("forename") String firstname); 
} 

और जब से विधि लागू सेवा में भंडार, फिर आप उन पैरामीटर को पारित कर सकते हैं।

-1

यदि हम JpaRepository का उपयोग कर रहे हैं तो यह आंतरिक रूप से प्रश्नों को बनाएगा।

नमूना

findByLastnameAndFirstname (स्ट्रिंग lastname, स्ट्रिंग firstname)

findByLastnameOrFirstname (स्ट्रिंग lastname, स्ट्रिंग firstname)

findByStartDateBetween (तिथि DATE1, तिथि 2)

findById (int आईडी)

नोट

मान लीजिए अगर हम तो जटिल क्वेरी की जरूरत है हम जैसे

@Query("SELECT salesOrder FROM SalesOrder salesOrder WHERE salesOrder.clientId=:clientId AND salesOrder.driver_username=:driver_username AND salesOrder.date>=:fdate AND salesOrder.date<=:tdate ") 
@Transactional(readOnly=true) 
List<SalesOrder> findAllSalesByDriver(@Param("clientId")Integer clientId, @Param("driver_username")String driver_username, @Param("fdate") Date fDate, @Param("tdate") Date tdate); 
-2
@Autowired 
private EntityManager entityManager; 

@RequestMapping("/authors/{fname}/{lname}") 
    public List actionAutherMulti(@PathVariable("fname") String fname, @PathVariable("lname") String lname) { 
     return entityManager.createQuery("select A from Auther A WHERE A.firstName = ?1 AND A.lastName=?2") 
       .setParameter(1, fname) 
       .setParameter(2, lname) 
       .getResultList(); 
    } 
0

मैनुअल प्रश्नों लिखने के लिए आप भी एक अंतरफलक डिफ़ॉल्ट विधि के साथ इसे हल कर सकता है की जरूरत है:

@Query(select p from Person p where p.forename = :forename and p.surname = :surname) 
User findByForenameAndSurname(@Param("surname") String lastname, 
         @Param("forename") String firstname); 

default User findByName(Name name) { 
    return findByForenameAndSurname(name.getLastname(), name.getFirstname()); 
} 

बेशक आपके पास अभी भी वास्तविक भंडार कार्य सार्वजनिक रूप से होगा isible ...

संबंधित मुद्दे