2010-11-08 12 views
5

पर कस्टम क्वेरी संकेत निर्दिष्ट कर सकते हैं हमें हमारे आवेदन निष्पादित प्रत्येक क्वेरी के लिए क्वेरी नंबर जोड़ना होगा।क्या हम जेपीए नामांकित क्वार्टर

EX: चुनें * से ... जहां ... QUERYNO 123456;

ओपनजेपीए क्वेरी संकेतों का समर्थन करता है, लेकिन केवल विशिष्ट कार्यान्वयन पर विशिष्ट संकेतों के लिए।

... 
Query q = em.createQuery("select m from Magazine m where ... "); 
q.setHint("openjpa.hint.OptimizeResultCount", new Integer(2)); 
q.setHint("openjpa.FetchPlan.ReadLockMode","WRITE"); 
List r = q.getResultList(); 
... 

लेकिन जेपीए कल्पना, और openjpa के अनुसार, "अमान्य संकेत या संकेत है जो एक विशेष डेटाबेस द्वारा संसाधित नहीं किया जा सकता अनदेखी कर रहे हैं। अन्यथा, अवैध संकेत एक ArgumentException फेंके जाने का परिणाम देगा।" इसलिए संकेत के रूप में "QUERYNO" निर्दिष्ट करने पर कोई प्रभाव नहीं पड़ता है।

मैं कार्यावधि में निर्दिष्ट करने के लिए एक कस्टम क्वेरी सुझाव कैसे बनाऊं?

... क्वेरी q = em.createQuery ("मैगज़ीन एम से एम का चयन करें ..."); q.setHint ("com.me.CustomQueryNoHint", नया इंटीजर (2234)); सूची आर = q.getResultList(); ...

+0

+ 1 जेपीए 2 को अभी भी कुछ फीचर्स की आवश्यकता है;) – dira

+0

मेरे पिछले उत्तर में अपडेट किए गए उत्तर को देखें। – dira

+0

@ becomputer06 - मुझे लगता है कि मैं स्पष्ट रूप से मेरी ज़रूरत को व्यक्त नहीं कर रहा हूं। आपका बाद का समाधान केवल लॉगिंग पर लागू होता है, और डेटाबेस को नहीं भेजा जाता है। QUERYNO एक विशिष्ट खंड है, जैसे कि X ROWS के लिए कहां या ऑप्टिमाइज़ करें। http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.sqlref/db2z_sql_querynoclause.htm – Eddie

उत्तर

0

संकेत के रूप में "QUERYNO" निर्दिष्ट करने पर कोई प्रभाव नहीं पड़ता है।

सही। आपके द्वारा उद्धृत दस्तावेज़ के अनुसार, "QUERYNO" एक अमान्य संकेत है, इसलिए इसे अनदेखा किया जाता है। डॉक्टर कुछ हद तक भ्रमित है, लेकिन मुझे विश्वास है कि आपके द्वारा देखे गए व्यवहार का समर्थन करने के लिए व्याख्या की जा सकती है। :-)

मैं रनटाइम पर निर्दिष्ट करने के लिए कस्टम क्वेरी संकेत कैसे बना सकता हूं?

एक बहुत लम्बे काम है कि। मुझे विश्वास नहीं है कि ओपनजेपीए को कस्टम क्वेरी संकेत लिखने की अनुमति देने के लिए डिज़ाइन किया गया था।

मैं हर एसक्यूएल के लिए एक विशिष्ट स्ट्रिंग संलग्न करने के लिए इच्छुक के अपने वास्तविक समस्या के बारे में कुछ और सोचा और मुझे नहीं लगता कि यह OpenJPA में करने के लिए बहुत आसान हो जाएगा। शायद आप अपने जेडीबीसी ड्राइवर के लिए एक रैपर लिख सकते हैं और क्या यह आपकी एसक्यूएल को प्रत्येक एसक्यूएल में जोड़ सकता है?

+0

क्या रैपर को वेब कंटेनर में निर्दिष्ट करने की आवश्यकता होगी डेटा स्रोत कॉन्फ़िगरेशन, या क्या मैं ओपनजेपीए को कंटेनर द्वारा दिए गए किसी भी ड्राइवर के साथ एक रैपर का उपयोग करने के लिए कह सकता हूं? समस्या यह है कि हमारे डीबीए केवल एक बहुत ही विशिष्ट जेडीबीसी चालक को अनुमति देते हैं, और सभी वातावरणों पर इसकी कॉन्फ़िगरेशन का प्रबंधन करते हैं, इसलिए जब तक यह पूरी तरह से .war पक्ष से नहीं किया जा सकता है, यह तुरंत नहीं है। – Eddie

0

नहीं पूरा जवाब लेकिन सिर्फ एक सूचक ...

QueryCounter

public class QueryCounter { 
    private static long COUNTER = 0; 

    private static long next() { 
     return ++COUNTER; 
    } 

    private static String getHintValue() { 
     return "/*Query No. " + next() + " */"; 
    } 

    public static void setQueryCount(Query query) { 
     /* EclipseLink */ 
     //query.setHint(QueryHints.HINT, getHintValue()); 
      query.setHint("eclipselink.sql.hint", getHintValue()); 

     /* OpenJPA + Oracle */ 
     //query.setHint("openjpa.hint.OracleSelectHint", getQueryHint()); 

     /* OpenJPA + MySQL */ 
     //query.setHint("openjpa.hint.MySQLSelectHin", getQueryHint()); 
    } 
} 

प्रयोग

Organization sun = new Organization("Sun"); 
     em.persist(sun); 
     tx.commit(); 
     Assert.assertNotNull(sun.getEntityId()); 

     Query query = em.createQuery("SELECT org.entityId FROM Organization org WHERE org.entityId = " + sun.getEntityId()); 
     QueryCounter.setQueryCount(query); 
     query.getResultList(); 

     /*ServerSession does NOT log ReadObjectQuery??*/ 
     query = em.createQuery("SELECT org FROM Organization org WHERE org.entityId = " + sun.getEntityId()); 
     QueryCounter.setQueryCount(query); 
     query.getResultList(); 

     query = em.createQuery("SELECT org.entityId FROM Organization org WHERE org.entityId = " + sun.getEntityId()); 
     QueryCounter.setQueryCount(query); 
     query.getResultList(); 

कंसोल

[EL Finest]: 2010-11-20 19:06:16.45--UnitOfWork(717879615)--Thread(Thread[main,5,main])--Execute query ReportQuery(referenceClass=Organization sql="SELECT entity_id FROM organization_tt WHERE (entity_id = ?)") 
[EL Fine]: 2010-11-20 19:06:16.475--ServerSession(699542937)--Connection(1949550475)--Thread(Thread[main,5,main])--SELECT /*Query No. 1 */ entity_id FROM organization_tt WHERE (entity_id = ?) 
    bind => [1] 
[EL Finest]: 2010-11-20 19:06:23.372--UnitOfWork(717879615)--Thread(Thread[main,5,main])--Execute query ReadObjectQuery(referenceClass=Organization sql="SELECT entity_id, name FROM organization_tt WHERE (entity_id = ?)") 
[EL Finest]: 2010-11-20 19:06:35.916--UnitOfWork(717879615)--Thread(Thread[main,5,main])--Execute query ReportQuery(referenceClass=Organization sql="SELECT entity_id FROM organization_tt WHERE (entity_id = ?)") 
[EL Fine]: 2010-11-20 19:06:35.92--ServerSession(699542937)--Connection(1949550475)--Thread(Thread[main,5,main])--SELECT /*Query No. 3 */ entity_id FROM organization_tt WHERE (entity_id = ?) 
    bind => [1] 

ओपनजेपीए की समान अवधारणा 1.8.7. Database-Specific Hints है। देखें कि ये विशिष्ट संकेत आपके उद्देश्य को हल कर सकते हैं या नहीं।

UPDATED उत्तर

@Eddie, अगर यह आपकी मदद कर सकता ...........

CustomLogFactory

public class MyLogFactory extends org.apache.openjpa.lib.log.LogFactoryImpl { 

    /* copied from LogFactoryImpl.NEWLINE */ 
    private static final String NEWLINE = J2DoPrivHelper.getLineSeparator(); 

    private boolean sqlLogger; 

    @Override 
    public Log getLog(String channel) { 
     if("openjpa.jdbc.SQL".equals(channel)) { // OR equalsIgnoreCase(channel) ??? 
      sqlLogger = true; 
     } 
     return super.getLog(channel); 
    } 

    @Override 
    protected LogImpl newLogImpl() { 
     if(sqlLogger) { 
      sqlLogger = false; /* once an SQL Logger is created, we dont't need any more instances */ 
      return new LogImpl() { 
       private long sqlCounter = 0; 

       @Override 
       protected String formatMessage(short level, String message, Throwable t) { 
        if(isSQLString(message)) { 
         StringBuffer formattedMessage = new StringBuffer(super.formatMessage(level, message, t)); 
         StringBuffer queryNo = new StringBuffer(); 
         queryNo.append(" [Query # ").append(++sqlCounter).append("]").append(NEWLINE); 
         formattedMessage.delete(formattedMessage.length() - NEWLINE.length(), formattedMessage.length()); 
         formattedMessage.append(queryNo); 
         return formattedMessage.toString(); 
        } 
        return super.formatMessage(level, message, t); 
       } 

       /* just a sample implementation; checks whether message contains the word "executing" 
       * more concrete implementation should check the message for SELECT, UPDATE, INSERT INTO, ALTER.... clauses */ 
       private boolean isSQLString(String message) { 
        if(message.contains("executing")) { 
         return true; 
        } 
        return false; 
       } 

      }; 
     } 
     return super.newLogImpl(); 
    } 

} 

peristence.xml देखना

<property name="openjpa.Log" value="org.opensource.logger.MyLogFactory(DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE)"/> 

टेस्ट

EntityManager em = Persistence.createEntityManagerFactory("default").createEntityManager(); 
EntityTransaction tx = em.getTransaction(); 
tx.begin(); 
Person person = new Person(); 
person.setName("Bond-OO7"); 
person.setAge(22); 
em.persist(person); 
tx.commit(); 
em.close(); 

कंसोल

............ 
2084 default TRACE [main] openjpa.jdbc.SQL - <t 346613126, conn 1551158018> executing prepstmnt 556472773 SELECT SEQUENCE_OWNER AS SEQUENCE_SCHEMA, SEQUENCE_NAME FROM ALL_SEQUENCES [Query # 1] 
2136 default TRACE [main] openjpa.jdbc.SQL - <t 346613126, conn 1551158018> [52 ms] spent 
2305 default TRACE [main] openjpa.jdbc.SQL - <t 346613126, conn 2026561073> executing prepstmnt 6637010 INSERT INTO Person (id, age, name) VALUES (?, ?, ?) [params=?, ?, ?] [Query # 2] 
2306 default TRACE [main] openjpa.jdbc.SQL - <t 346613126, conn 2026561073> [1 ms] spent 
............ 

Reference

+0

धन्यवाद, लेकिन ऐसा लगता है कि आप केवल * * * के बीच टिप्पणियां जोड़ रहे हैं/जो ओपनजेपीए के लिए ओरेकलहिंट का उपयोग करके लाभ उठा सकते हैं। हालांकि, QUERYNO कोई टिप्पणी नहीं है, लेकिन एक डीबी 2 क्वेरी क्लॉज है, यह बयान के अंत में और टिप्पणी ब्लॉक के बाहर होना चाहिए। और जैसा कि प्रलेखन आप इंगित करते हैं, ओपनजेपीए के लिए संकेत केवल ओरेकल और माईएसक्यूएल के लिए उपयोग किए जाते हैं। मेरे डीबी 2 शब्दकोश के लिए या तो संकेत स्ट्रिंग को अनदेखा किया जाता है। – Eddie

0

बजाय JPQL का उपयोग करें और क्वेरी में विक्रेता विशिष्ट सामान के लिए मजबूर करने का प्रयास करें, आप एक देशी लेखन माना जाता है क्वेरी जो एक इकाई रिटर्न प्रकार के लिए मैप किया गया है?

em.createNativeQuery(YOUR_DB2_NATIVE_SQL_QUERY_STRING, Magazine.class) 

इसके बाद से अपनी मूल क्वेरी स्तंभ मानों उस संस्था वर्ग में मैप कॉलम के साथ मेल का चयन करने की जरूरत है आप के लिए और अधिक काम हो जाएगा, लेकिन यह काम करना चाहिए। जब आप देशी एसक्यूएल का उपयोग करते हैं तो क्वेरी इंजन को विक्रेता-विशिष्ट एसक्यूएल को पार्स और व्याख्या नहीं करना चाहिए, इसलिए अंत में आपका डीबी 2-विशिष्ट क्लॉज रनटाइम पर अंतर्निहित डेटाबेस से गुज़रना चाहिए।

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