JPA द्वारा जारी किए गए SQL प्रश्नों को कैसे देखें?


155

जब मेरा कोड इस तरह से कॉल जारी करता है:

entityManager.find(Customer.class, customerID);

मैं इस कॉल के लिए SQL क्वेरी कैसे देख सकता हूं? यह मानते हुए कि मेरे पास डेटाबेस सर्वर का उपयोग प्रोफाइल / कॉल की निगरानी करने के लिए नहीं है, क्या मेरे आईडीई के भीतर लॉग इन करने या देखने का कोई तरीका है जो कि जेपीए कॉल द्वारा जारी एसक्यूएल क्वेरी है? मैं jTDS ड्राइवर का उपयोग करके SQL Server 2008 R2 के खिलाफ जा रहा हूं।


8
जेपीए प्रदाता क्या है? मेरा मानना ​​है कि यह सेटिंग प्रदाता विशिष्ट है।
btiernay

@ साजी कृपया आप axtavt के उत्तर को स्वीकृत के रूप में चिह्नित कर सकते हैं ताकि यह आगंतुकों को आपके प्रश्न को सीधे इस उत्तर पर ले जाए?
8bitjunkie

जवाबों:


332

लॉगिंग विकल्प प्रदाता-विशिष्ट हैं। आपको यह जानने की आवश्यकता है कि आप किस जेपीए कार्यान्वयन का उपयोग करते हैं

  • सीतनिद्रा में होना ( यहाँ देखें ):

    <property name = "hibernate.show_sql" value = "true" />
  • एक्लिप्सलिंक ( यहां देखें ):

    <property name="eclipselink.logging.level" value="FINE"/>
  • OpenJPA ( यहाँ देखें ):

    <property name="openjpa.Log" value="DefaultLevel=WARN,Runtime=INFO,Tool=INFO,SQL=TRACE"/>
  • DataNucleus ( यहाँ देखें ):

    लॉग श्रेणी DataNucleus.Datastore.Nativeको एक स्तर पर सेट करें , जैसे DEBUG


4
@ साजी: आपको यह संकेत देने के लिए यह उत्तर चेक-मार्क देना चाहिए कि यह स्वीकृत उत्तर है। यह मेरे लिए बहुत अच्छा काम करता है, हाइबरनेट का उपयोग करके। यदि आप इस उत्तर का अनुमोदन करते हैं, तो आपको और उत्तरदाता को अधिक अंक और stackoverflow.com पर अधिक अनुमतियां मिलेंगी।
LS

57
आप अपने शरीर में इस लाइन को लगाएंगे। जो किसी भी शरीर के लिए जिज्ञासु है। यह <गुण> नोड के अंतर्गत होगा ... क्षमा करें यदि यह स्पष्ट है, तो मैं सिर्फ इस बारे में उलझन में था कि इसे स्वयं कहां रखा जाए।
SoftwareSavant

5
हाइबरनेट और log4j का उपयोग करते समय, आप DEBUG को "org.hibernate.SQL" लकड़हारा भी सेट कर सकते हैं ( javalobby.org/java/forums/t44119.html )
मोशेइल

इसके अतिरिक्त, ऐसा लगता है कि <गुण> नोड को <दृढ़ता-इकाई> के भीतर बाकी सभी चीजों के नीचे रहने की आवश्यकता है। <3 एक्सएमएल।
टॉम स्पर्लिंग

1
इन संपत्तियों को कहां सेट किया जाना चाहिए?
एलेक्स वर्डेन

34

इसके अलावा, यदि आप EclipseLink का उपयोग कर रहे हैं और SQL पैरामीटर मान को आउटपुट करना चाहते हैं, तो आप इस संपत्ति को अपनी दृढ़ता में जोड़ सकते हैं। XML फ़ाइल:

<property name="eclipselink.logging.parameters" value="true"/>

क्या इंटेलीज में बाध्यकारी मूल्यों को प्राप्त करने का कोई विकल्प है?
विनियस एम

15

यदि आप अपने लकड़हारे के रूप में हाइबरनेट और लॉगबैक का उपयोग करते हैं तो आप निम्नलिखित का उपयोग कर सकते हैं (केवल बाइंडिंग दिखाता है और परिणाम नहीं):

<appender
    name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -
            %msg%n</pattern>
    </encoder>
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator>
            <expression>return message.toLowerCase().contains("org.hibernate.type") &amp;&amp;
                logger.startsWith("returning");</expression>
        </evaluator>
        <OnMismatch>NEUTRAL</OnMismatch>
        <OnMatch>DENY</OnMatch>
    </filter>
</appender>

org.hibernate.SQL = DEBUG क्वेरी को प्रिंट करता है

<logger name="org.hibernate.SQL">
    <level value="DEBUG" />
</logger>

org.hibernate.type = TRACE बाइंडिंग प्रिंट करता है और सामान्य रूप से परिणाम, जो कस्टम फ़िल्टर के माध्यम से दबाया जाएगा

<logger name="org.hibernate.type">
    <level value="TRACE" />
</logger>

आपको जीनो निर्भरता (http://logback.qos.ch/manual/filters.html#JaninoEventEvaluator) की आवश्यकता है:

<dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>janino</artifactId>
    <version>2.6.1</version>
</dependency>

15

EclipseLink में एक विशेष क्वेरी के लिए एसक्यूएल पाने के लिए रनटाइम पर आप डेटाबेसविक एपीआई का उपयोग कर सकते हैं:

Query query = em.createNamedQuery("findMe"); 
Session session = em.unwrap(JpaEntityManager.class).getActiveSession(); 
DatabaseQuery databaseQuery = ((EJBQueryImpl)query).getDatabaseQuery(); 
databaseQuery.prepareCall(session, new DatabaseRecord());

String sqlString = databaseQuery.getSQLString();

इस SQL ​​में होगा? मापदंडों के लिए। एसक्यूएल को तर्कों के साथ अनुवादित करने के लिए आपको पैरामीटर मानों के साथ एक डेटाबेसरॉर्ड की आवश्यकता होती है।

DatabaseRecord recordWithValues= new DatabaseRecord();
recordWithValues.add(new DatabaseField("param1"), "someValue");

String sqlStringWithArgs = 
         databaseQuery.getTranslatedSQLString(session, recordWithValues);

स्रोत: SQL क्वेरी के लिए कैसे प्राप्त करें


रिकॉर्डविथाल्यूल्स क्या है? क्या इसे डेटाबेस से प्राप्त करना संभव है या EJBQueryImpl?
zmeda

1
रिकार्ड तर्क (रिकार्ड, XMLRecord) कि क्वेरी तर्कों शामिल में से एक है
टोमाज़

अगर मेरे पास कुछ ऐसा है जैसे Query myQuery = unitManager.createNamedQuery ("MyEntity.findMe"); myQuery.setParameter ( "param1", "someValue); myQuery से recordWithValues प्राप्त करने के लिए कैसे?
zmeda

RecordWithValues ​​निर्माण को शामिल करने के लिए मेरे जवाब को अपडेट किया।
टॉमाज़

अरे क्या आप जानते हैं कि ग्रहण काल ​​के लिए यह कैसे करना है जो JPA के साथ नहीं चल रहा है? (मुझे यह भी नहीं पता कि यह वास्तव में क्या है, लेकिन इसने एक कार्यक्षेत्र एप्लिकेशन से मैपिंग-क्लासेस उत्पन्न किया है .... हालांकि मेरे पास कोई ईएम नहीं है, लेकिन केवल एक toplink सेवा मैं एक सत्र का अनुरोध कर सकता हूं लेकिन यह किसी भी क्वेरी के बारे में नहीं जानता है। " ReadAllQuery, ExpressionBuilder और Expression जैसी कक्षाओं का उपयोग करें। आपको इसका उत्तर देने की आवश्यकता नहीं है यदि इसका बहुत अस्पष्ट (इस पर प्रो नहीं, JPA के लिए उपयोग किया गया im) मैं अगले 48 घंटों के भीतर इस टिप्पणी को हटा दूंगा और स्पष्ट प्रश्न पूछने का प्रयास करूंगा;)
जेबीए

7

OpenJPA में सभी SQL और मापदंडों को देखने के लिए, इन दो मापदंडों को दृढ़ता में रखें। xml:

<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
<property name="openjpa.ConnectionFactoryProperties" value="PrintParameters=true" />

5

यदि आप सटीक प्रश्नों को पूरी तरह से पैरामीटर मान और रिटर्न मान के साथ देखना चाहते हैं, तो आप jdbc प्रॉक्सी ड्राइवर का उपयोग कर सकते हैं। यह सभी jdbc कॉल को इंटरसेप्ट करेगा और उनके मानों को लॉग करेगा। कुछ परदे के पीछे:

  • log4jdbc
  • jdbcspy

वे कुछ अतिरिक्त सुविधाएँ भी प्रदान कर सकते हैं, जैसे प्रश्नों के निष्पादन के समय को मापना और आँकड़ों को इकट्ठा करना।


4

Log4j ( src \ log4j.xml ) का उपयोग करके उदाहरण :

<?xml version="1.0" encoding="UTF-8" ?>

<appender name="CA" class="org.apache.log4j.AsyncAppender">
    <param name="BufferSize" value="512"/>
    <appender-ref ref="CA_OUTPUT"/>
</appender>
<appender name="CA_OUTPUT" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="[%p] %d %c %M - %m%n"/>
    </layout>
</appender>

<logger name="org.hibernate.SQL" additivity="false">
    <level value="DEBUG"/>
    <appender-ref ref="CA"/>
</logger>

<root>
    <level value="WARN"/>
    <appender-ref ref="CA"/>
</root>


1
कृपया अपने उत्तर को थोड़ा और स्पष्ट करें। मुझे लगता है कि मुख्य खंड org.hibernate.SQL खंड है?
जैकडेव

2

मुझे लगता है कि मैंने दूसरों के लिए उपयोगी हो सकता है एक धोखा दिया है। सभी उदाहरणों में, format_sqlयदि आप लॉग इन क्वेरी को एक पंक्ति (कोई सुंदर मुद्रण) पर रखना चाहते हैं, तो आप संपत्ति को निकाल सकते हैं।

सुंदर मानक बाहर करने के लिए एसक्यूएल प्रश्नों प्रिंट के बिना तैयार बयान के मापदंडों और एक प्रवेश ढांचे के अनुकूलन के बिना :

application.properties फ़ाइल:

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

application.yml फ़ाइल:

spring:
  jpa:
    show-sql: true
    properties:
      hibernate:
        format_sql: true

लॉगिंग फ्रेमवर्क का उपयोग करके तैयार किए गए बयानों के मापदंडों के साथ सुंदर प्रिंट एसक्यूएल प्रश्न :

application.properties फ़ाइल:

spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

application.yml फ़ाइल:

spring:
  jpa:
    properties:
      hibernate:
        format_sql: true
logging:
  level:
    org:
      hibernate:
        SQL: DEBUG
        type:
          descriptor:
            sql:
              BasicBinder: TRACE

एक लॉगिंग ढांचे का उपयोग करके तैयार किए गए बयानों के मापदंडों के बिना सुंदर प्रिंट एसक्यूएल प्रश्न :

application.properties फ़ाइल:

spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG

application.yml फ़ाइल:

spring:
  jpa:
    properties:
      hibernate:
        format_sql: true
logging:
  level:
    org:
      hibernate:
        SQL: DEBUG

स्रोत (और अधिक विवरण): https://www.baeldung.com/sql-log-spring-boot


1

इसके अतिरिक्त, यदि WildFly / JBoss का उपयोग किया जाता है, तो org.hibernate का DEBUG लॉगिंग स्तर निर्धारित करें

वाइल्डली में हाइबरनेट लॉगिंग


1

एक और अच्छा विकल्प यदि आपके पास बहुत अधिक लॉग है और आप केवल एक अस्थायी के रूप में रखना चाहते हैं System.out.println(), तो आप अपने प्रदाता के आधार पर कर सकते हैं:

CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<ExaminationType> criteriaQuery = criteriaBuilder.createQuery(getEntityClass()); 

/* For Hibernate */
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(org.hibernate.Query.class).getQueryString());

/* For OpenJPA */ 
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(org.apache.openjpa.persistence.QueryImpl.class).getQueryString());

/* For EclipseLink */
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(JpaQuery.class).getSQLString());

हमारे ओपनजापा आधारित कार्यान्वयन में, यह पैरामीरिज्ड क्वेरी के लिए क्वेरी के भाग के रूप में पैरामीटर नहीं दिखाता है।
समयमाघ

1

यदि आप स्प्रिंग फ्रेमवर्क का उपयोग कर रहे हैं। नीचे के रूप में अपनी application.properties फ़ाइल को संशोधित करें

#Logging JPA Queries, 1st line Log Query. 2nd line Log parameters of prepared statements 
logging.level.org.hibernate.SQL=DEBUG  
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE  

#Logging JdbcTemplate Queries, 1st line Log Query. 2nd line Log parameters of prepared statements 
logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG  
logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE  

0

मैं हाइबरनेट का उपयोग नहीं कर रहा हूं। AFAIK, सिर्फ सादा पुराने जेपीए। showSQL एक हाइबरनेट संपत्ति की तरह दिखता है। क्या वह मेरे मामले में काम करेगा?
साजि

ऐसा लगता है कि उत्तर नहीं है, मुझे लॉग में कोई SQL दिखाई नहीं देता है।
साजि

1
साजि, आप अपनी दृढ़ता पर गुणों की घोषणा कैसे करते हैं। xml?
गोंडिम

0

स्प्रिंग बूट के साथ बस जोड़ें: spring.jpa.show-sql = application.properties के लिए सही। यह क्वेरी दिखाएगा लेकिन वास्तविक मापदंडों के बिना (आप देखेंगे? प्रत्येक पैरामीटर के बजाय)।


0

खोजपूर्ण विकास के दौरान, और मैं जिस विशिष्ट विधि को जांचना चाहता हूं, उस पर SQL डीबगिंग लॉगिंग को फोकस करने के लिए, मैं उस विधि को निम्नलिखित लकड़हारा बयानों से सजाता हूं:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;

((ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.hibernate.SQL")).setLevel(Level.DEBUG);
entityManager.find(Customer.class, customerID);
((ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.hibernate.SQL")).setLevel(Level.INFO);

0

SQL (persistence.xml config) आउटपुट के लिए ग्रहण

<property name="eclipselink.logging.level.sql" value="FINE" />

-2

वहाँ एक फ़ाइल है, जिसे persistence.xml कहा जाता है, Ctrl + Shift + R दबाएं और इसे खोजें, फिर, इसमें showSQL जैसी कुछ जगह लिखी गई है।

बस इसे सच मानिए

मुझे यकीन नहीं है कि सर्वर को डिबग मोड के रूप में शुरू किया जाना चाहिए। कंसोल पर बनाई गई SQL की जाँच करें।


यह केवल दिखाने के लिए पैरामीटर sql स्टेटमेंट दिखाने के लिए पर्याप्त नहीं है? मापदंडों के लिए।
अबूज़र ताहा कानत

1
"कुछ showSQL की तरह" जवाब नहीं है। और Ctrl + Shift + R? आपने IDE के बारे में एक धारणा बनाई है।
8bitjunkie
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.