2015-07-10 14 views
6

का उपयोग कर औसत दिनांक अंतर मैं क्वेरीरीएसएल का उपयोग कर औसत दिनांक अंतर की गणना करने की कोशिश कर रहा हूं।querydsl-jpa/querydsl-sql

मैंने a small project को एक सरल तरीके से पूरा करने की कोशिश करने के लिए बनाया है (असली क्वेरी बहुत अधिक जटिल है, जिसमें कई शामिल/जहां/सॉर्ट क्लोज़ हैं)। हमारे पास Customer कक्षा birthDate फ़ील्ड है, और हम अपने ग्राहकों की औसत आयु, सेकंड में प्राप्त करने की कोशिश कर रहे हैं। हम अधिकतम उम्र भी चाहते हैं, लेकिन चलिए इस पोस्ट के लिए औसत पर ध्यान केंद्रित करते हैं।

I tried writing this query using querydsl-jpa है, लेकिन यह एक अस्पष्ट त्रुटि के साथ विफल:

java.lang.NullPointerException 
     at org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions$AvgFunction.determineJdbcTypeCode(StandardAnsiSqlAggregationFunctions.java:106) 
     at org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions$AvgFunction.render(StandardAnsiSqlAggregationFunctions.java:100) 
     at org.hibernate.hql.internal.ast.SqlGenerator.endFunctionTemplate(SqlGenerator.java:233) 
     [...] 

मैं भी अन्य तरीकों की कोशिश की, NumberTemplate.create(Double.class, "{0} - {1}", DateExpression.currentDate(), customer.birthDate).avg() का उपयोग कर की तरह है, लेकिन यह सही मान वापस नहीं करता है। अगर हम सेकंड में डेट अंतर प्राप्त करना चाहते हैं, तो ऐसा लगता है कि हमें डेटाबेस-विशिष्ट दिनांक/समय अंतर कार्यों को कॉल करने का कोई तरीका ढूंढना होगा, न केवल शून्य चिह्न का उपयोग करें।

दुख की बात है, computing a date difference doesn't seem to be possible in JPQL, तो मुझे लगता है कि querydsl-jpa की सीमाएं भी हैं। तो हमें मूल एसक्यूएल क्वेरी लिखनी होगी, या कुछ हैक ढूंढने के लिए QueryDsl- जेनरेट जेपीक्यूएल एक मूल डेटाबेस फ़ंक्शन कॉल करें।

JPA 2.1 added support for invoking database functions, लेकिन एक समस्या है: MySQL फ़ंक्शन फॉर्म TIMESTAMPDIFF(SECOND, '2012-06-06 13:13:55', '2012-06-06 15:20:18') लेता है। यह संभवतः संभव होगा यदि पहला पैरामीटर (SECOND) एक स्ट्रिंग था, लेकिन ऐसा लगता है कि यह किसी प्रकार का निरंतर संदर्भ है, और यह पहले पैरामीटर के साथ जेपीक्यूएल उत्पन्न करने के लिए जटिल लगता है।

QueryDSL added support for date differences, लेकिन ऐसा लगता है कि अधिकांश कोड querydsl-sql प्रोजेक्ट में रहता है, इसलिए मुझे आश्चर्य है कि क्या मैं querydsl-jpa से इसका लाभ उठा सकता हूं।

यहाँ मेरी प्रश्न हैं:

  1. यह querydsl-जेपीए का उपयोग कर औसत तारीख अंतर का परिकलन करना संभव है, यह शायद जेपीए 2.1 समर्थन (शायद Expressions.numberTemplate() का प्रयोग करके) का उपयोग कर देशी डेटाबेस कार्यों कॉल आ रही हैं? या क्या हम querydsl-sql का उपयोग करने के लिए मजबूर हैं?

  2. अगर हमें querydsl-sql का उपयोग करना है, तो हम QCustomer और SCustomer दोनों कैसे उत्पन्न करते हैं? QCustomer वर्तमान में प्लगइन "com.mysema.maven: apt-maven-plugin" प्लगइन का उपयोग कर ग्राहक इकाई से उत्पन्न होता है। अगर मैं सही ढंग से समझ गया, I have to use a different plugin (com.querydsl: querydsl-maven-plugin) SCustomer क्वेरी प्रकार उत्पन्न करने के लिए?

    querydsl-sql-example पर देखते समय, मुझे कोई इकाई वर्ग नहीं दिखाई देता है, तो मुझे लगता है कि क्वेरी स्कीमा से क्वेरीरीएलएल द्वारा क्वेरी प्रकार जेनरेट किए जाते हैं? क्या इसके बजाय इकाई से SCustomer क्वेरी प्रकार उत्पन्न करने का कोई तरीका है, जैसे हम querydsl-jpa के साथ करते हैं?

  3. यदि हम querydsl-sql का उपयोग करते हैं, तो क्या हमारे querydsl-jpa predicates/reorts/querydsl-sql क्वेरी में खंडों में "पुनः उपयोग" करने का कोई तरीका है? या क्या हमें querydsl-sql-specific कक्षाओं का उपयोग करके उस कोड को डुप्लिकेट करना है?

  4. मैं भी TIMESTAMPDIFF(SECOND, x, y) के लिए एक डेटाबेस समारोह है कि प्रतिनिधियों को बनाने पर विचार कर रहा हूँ, लेकिन यह बहुत पोर्टेबल नहीं है ...

  5. मैं कुछ याद आ रही है? क्या मैं ऐसा करने का प्रयास करने का एक आसान तरीका है?

उत्तर

1

टेम्पलेट अभिव्यक्तियों का उपयोग करके आप Querydsl क्वेरी में किसी भी कस्टम जेपीक्यूएल स्निपेट को इंजेक्ट करने में सक्षम होना चाहिए। उसे आपके पहले प्रश्न का उत्तर देना चाहिए।

एक ही प्रोजेक्ट में querydsl-jpa और querydsl-sql दोनों का उपयोग करना संभव है, लेकिन कुछ जटिलता जोड़ता है।