2012-02-17 13 views
34

क्या आप कृपया निम्नलिखित कोडों को मानदंड निर्माता के "इन" ऑपरेटर का उपयोग करने के लिए कैसे मदद कर सकते हैं? मुझे "इन" का उपयोग करके उपयोगकर्ता नामों की सूची/सरणी का उपयोग करके फ़िल्टर करने की आवश्यकता है।जेपीए मानदंडबिल्डर - "IN" तुलना ऑपरेटर का उपयोग कैसे करें

मैंने जेपीए मानदंडबिल्डर - "इन" विधि का उपयोग करने की खोज करने की भी कोशिश की लेकिन अच्छे नतीजे नहीं मिल पाए। तो यदि आप मुझे इस विषय के लिए संदर्भ यूआरएल दे सकते हैं तो भी मैं वास्तव में सराहना करता हूं। धन्यवाद।

यहाँ मेरी कोड है:

//usersList is a list of User that I need to put inside IN operator 

CriteriaBuilder builder = getJpaTemplate().getEntityManagerFactory().getCriteriaBuilder(); 
CriteriaQuery<ScheduleRequest> criteria = builder.createQuery(ScheduleRequest.class); 

Root<ScheduleRequest> scheduleRequest = criteria.from(ScheduleRequest.class); 
criteria = criteria.select(scheduleRequest); 

List<Predicate> params = new ArrayList<Predicate>(); 

List<ParameterExpression<String>> usersIdsParamList = new ArrayList<ParameterExpression<String>>(); 

for (int i = 0; i < usersList.size(); i++) { 
ParameterExpression<String> usersIdsParam = builder.parameter(String.class); 
params.add(builder.equal(scheduleRequest.get("createdBy"), usersIdsParam)); 
usersIdsParamList.add(usersIdsParam); 
} 

criteria = criteria.where(params.toArray(new Predicate[0])); 

TypedQuery<ScheduleRequest> query = getJpaTemplate().getEntityManagerFactory().createEntityManager().createQuery(criteria); 

for (int i = 0; i < usersList.size(); i++) { 
query.setParameter(usersIdsParamList.get(i), usersList.get(i).getUsername()); 
} 

List<ScheduleRequest> scheduleRequestList = query.getResultList(); 

आंतरिक क्वेरी स्ट्रिंग नीचे में बदल जाती है, इसलिए है क्योंकि यह उपयोग कर रहा है "और" मैं दो उपयोगकर्ताओं द्वारा बनाए गए रिकॉर्ड नहीं मिलता है।

select generatedAlias0 from ScheduleRequest as generatedAlias0 where (generatedAlias0.createdBy=:param0) and (generatedAlias0.createdBy=:param1) order by generatedAlias0.trackingId asc 

उत्तर

69

अगर मैं अच्छी तरह से समझ, आप User साथ ScheduleRequest जुड़ें और इकाई User की userName संपत्ति को in खंड लागू करना चाहते हैं।

मुझे इस स्कीमा पर थोड़ा सा काम करने की आवश्यकता होगी। लेकिन आप इस चाल के साथ प्रयास कर सकते हैं, जो आपके द्वारा पोस्ट किए गए कोड से कहीं अधिक पठनीय है, और Join भाग से बचाता है (क्योंकि यह मानदंड क्वेरी के बाहर Join तर्क को संभालता है)।

List<String> myList = new ArrayList<String>(); 
for (User u : usersList) { 
    myList.add(u.getUsername()); 
} 
Expression<String> exp = scheduleRequest.get("createdBy"); 
Predicate predicate = exp.in(myList); 
criteria.where(predicate); 

आदेश अधिक प्रकार सुरक्षित कोड आप भी इस लाइन की जगह Metamodel इस्तेमाल कर सकते हैं लिखने के लिए में:

Expression<String> exp = scheduleRequest.get("createdBy"); 
इस के साथ

:

Expression<String> exp = scheduleRequest.get(ScheduleRequest_.createdBy); 

अगर यह काम करता है, तो आप कर सकते हैं तर्क Criteria Query में तर्क जोड़ने का प्रयास करें। लेकिन अभी मैं इसका परीक्षण नहीं कर सकता, इसलिए मैं देखना चाहता हूं कि कोई और कोशिश करना चाहता है या नहीं।

+0

हाय पेरिफ, आपके उत्तर के लिए धन्यवाद। क्या मैं कृपया पूछ सकता हूं, "ScheduleRequest_" क्या है? मैं इसे कैसे बना सकता हूं? – Jemru

+2

यह आपके जेपीए प्रदाता द्वारा स्वत: जेनरेट की गई मेटामोडेल क्लास है। यदि आप हाइबरनेट का उपयोग कर रहे हैं, तो इस लिंक को देखें http://docs.jboss.org/hibernate/jpamodelgen/1.0/reference/en-US/html_single/ – perissf

+0

मेरे छद्म कोड को पढ़ना मुझे एक संभावित प्रकार की विसंगति दिखाई देती है। क्या आप उपयोगकर्ता नाम (स्ट्रिंग) या उपयोगकर्ता आईडी (इंटीजर/लांग) के साथ जुड़ रहे हैं? कृपया मुझे बताएं ताकि मैं अपना उत्तर – perissf

13

कोई सही उत्तर नहीं है हालांकि कोड स्निपेट मदद कर सकता है।

public <T> List<T> findListWhereInCondition(Class<T> clazz, 
      String conditionColumnName, Serializable... conditionColumnValues) { 
     QueryBuilder<T> queryBuilder = new QueryBuilder<T>(clazz); 
     addWhereInClause(queryBuilder, conditionColumnName, 
       conditionColumnValues); 
     queryBuilder.select(); 
     return queryBuilder.getResultList(); 

    } 


private <T> void addWhereInClause(QueryBuilder<T> queryBuilder, 
      String conditionColumnName, Serializable... conditionColumnValues) { 

     Path<Object> path = queryBuilder.root.get(conditionColumnName); 
     In<Object> in = queryBuilder.criteriaBuilder.in(path); 
     for (Serializable conditionColumnValue : conditionColumnValues) { 
      in.value(conditionColumnValue); 
     } 
     queryBuilder.criteriaQuery.where(in); 

    } 
+1

बहुत बहुत धन्यवाद @gbagga, इस बात ने मुझे बहुत मदद की! उपरोक्त विधि (exp.in (myList)) "CriteriaBuilder" का उपयोग करते समय काम नहीं करेगी। आपकी विधि वह है जिसे मानदंडबिल्डर का उपयोग करते समय "IN" खंड के लिए उपयोग किया जाना चाहिए। कुडोस! – roneo

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