JPA tarafından yayınlanan SQL sorguları nasıl görüntülenir?


155

Kodum böyle bir çağrı verdiğinde:

entityManager.find(Customer.class, customerID);

Bu arama için SQL sorgusunu nasıl görebilirim? Çağrıları profillemek / izlemek için veritabanı sunucusuna erişimim olmadığını varsayarsak, IDE içinde JPA çağrıları tarafından verilen ilgili SQL sorgularını günlüğe kaydetmenin veya görüntülemenin bir yolu var mı? Ben jTDS sürücüsünü kullanarak SQL Server 2008 R2 karşı gidiyorum.


8
JPA sağlayıcısı nedir? Bu ayarın sağlayıcıya özel olduğuna inanıyorum.
btiernay

@Sajee, axtavt'ın cevabını kabul edilen olarak işaretleyebilir misiniz, böylece ziyaretçileri sorunuza doğrudan bu cevaba yönlendirir mi?
8bitjunkie

Yanıtlar:


332

Günlük seçenekleri sağlayıcıya özeldir. Hangi JPA uygulamasını kullandığınızı bilmeniz gerekir.

  • Hazırda bekletme ( buraya bakın ):

    <property name = "hibernate.show_sql" value = "true" />
  • EclipseLink ( buraya bakın ):

    <property name="eclipselink.logging.level" value="FINE"/>
  • OpenJPA ( buraya bakın ):

    <property name="openjpa.Log" value="DefaultLevel=WARN,Runtime=INFO,Tool=INFO,SQL=TRACE"/>
  • DataNucleus ( buraya bakın ):

    Günlük kategorisini DataNucleus.Datastore.Nativeaşağıdaki gibi bir düzeye ayarlayın DEBUG.


4
@Sajee: Bu cevaba, bunun kabul edilen cevap olduğunu belirtmek için bir onay işareti vermelisiniz. Hibernate kullanarak benim için harika çalışıyor. Bu yanıtı onaylarsanız, siz ve yanıtlayan stackoverflow.com'da daha fazla puan ve daha fazla izin alırsınız.
LS

57
Bu satırı, currious olan herhangi bir beden için persistence.xml dosyasına koyacaksınız. <properties> düğümü altında ... Üzgünüm, bu açıksa, kendim nereye koyacağım konusunda kafam karıştı.
SoftwareSavant

5
Hazırda Beklet ve log4j kullanırken, "org.hibernate.SQL" günlükçüsünü DEBUG ( javalobby.org/java/forums/t44119.html ) olarak da ayarlayabilirsiniz
MosheElisha

Ayrıca, <perisellik> düğümünde <persistence-unit> içindeki her şeyin altında olması gerekiyor gibi görünüyor. <3 XML.
Tom Spurling

1
Bu özellikler nerede ayarlanmalıdır?
Alex Worden

34

Ayrıca, EclipseLink kullanıyorsanız ve SQL parametre değerlerini çıkarmak istiyorsanız, bu özelliği persistence.xml dosyanıza ekleyebilirsiniz:

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

Intellij'de bağlayıcı değerleri elde etmenin bir alternatifi var mı?
Vinícius M

15

Kayıt cihazınız olarak hazırda bekletme ve oturum açma özelliğini kullanırsanız aşağıdakileri kullanabilirsiniz (sonuçları değil, yalnızca bağlantıları gösterir):

<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 Sorguyu yazdırır

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

org.hibernate.type = TRACE , bağları ve normalde sonuçları özel filtre aracılığıyla bastırılacak şekilde yazdırır

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

Janino bağımlılığına ihtiyacınız var (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'te, belirli bir Sorgu için SQL'i çalışma zamanında almak için DatabaseQuery API'sını kullanabilirsiniz:

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();

Bu SQL içerecek mi? parametreler için. SQL'in bağımsız değişkenlerle çevrilmesini sağlamak için parametre değerlerine sahip bir DatabaseRecord gerekir.

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

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

Kaynak: Sorgu için SQL nasıl edinilir


RecordWithValues ​​nedir? DatabaseQuery veya EJBQueryImpl'den almak mümkün mü?
zmeda

1
Kayıt bağımsız değişkeni, sorgu bağımsız değişkenlerini içeren (Record, XMLRecord) öğelerinden biridir
Tomasz

Sorgu gibi bir şey varsa myQuery = entityManager.createNamedQuery ("MyEntity.findMe"); myQuery.setParameter ("param1", "someValue); myQuery'den recordWithValues ​​nasıl alınır?
zmeda

Cevabımı recordWithValues ​​oluşturmayı içerecek şekilde güncellendi.
Tomasz

Hey bunu JPA ile çalışmayan eclipseLink saçmalık için nasıl biliyor musun? (Ben bile tam olarak ne olduğunu bilmiyorum ama bir tezgah uygulaması eşleme sınıfları üretti .... Ancak ben bir EM ama sadece bir toplink Hizmet i bir Oturum talep edebilir ama herhangi bir sorgu bilmiyor. ReadAllQuery, ExpressionBuilder ve Expression gibi Sınıfları kullanın. Çok net değilse (bu bir profesyonel değilim, JPA'ya alıyorum) cevap vermeniz gerekmez, sonraki 48 saat içinde bu yorumu silecek ve daha net bir soru sormaya çalışacağız;)
JBA

7

OpenJPA'daki tüm SQL ve parametreleri görüntülemek için şu iki parametreyi persistence.xml dosyasına koyun:

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

5

Kesin sorguları parametre değerleri ve dönüş değerleri ile birlikte görmek istiyorsanız, bir jdbc proxy sürücüsü kullanabilirsiniz. Tüm jdbc çağrılarını kesecek ve değerlerini kaydedecektir. Bazı vekiller:

  • log4jdbc
  • jdbcspy

Ayrıca, sorgular için yürütme süresini ölçme ve istatistik toplama gibi bazı ek özellikler de sağlayabilirler.


4

Log4j ( src \ log4j.xml ) kullanan örnek :

<?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
Lütfen cevabınızı biraz daha açıklayınız. Ana bölüm org.hibernate.SQL bölümü olduğunu varsayalım?
JackDev

2

Başkaları için yararlı olabileceğini düşündüğüm bir hile sayfası hazırladım. Tüm örneklerde, format_sqlgünlüğe kaydedilen sorguları tek bir satırda tutmak istiyorsanız (güzel yazdırma yapılmaz) özelliği kaldırabilirsiniz .

Hazırlanan ifadelerin parametreleri olmadan ve bir günlükleme çerçevesinin optimizasyonları olmadan standart olarak SQL sorgularını yazdırın :

application.properties dosya:

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

application.yml dosya:

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

Bir günlük çerçevesi kullanarak hazırlanmış deyimlerin parametreleri ile SQL sorgularını güzel yazdırın :

application.properties dosya:

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

application.yml dosya:

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

Oldukça SQL sorguları yazdırmak olmadan bir günlük çerçevesini kullanarak hazırlanan tabloların parametreleri :

application.properties dosya:

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

application.yml dosya:

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

Kaynak (ve daha fazla ayrıntı): https://www.baeldung.com/sql-logging-spring-boot


1

Ayrıca, WildFly / JBoss kullanıyorsanız, org.hibernate günlük kaydı düzeyini DEBUG olarak ayarlayın

WildFly'de Hazırda Bekleme Günlüğü


1

Çok fazla günlüğünüz varsa ve yalnızca geçici olarak koymak istiyorsanız, başka bir iyi seçenekSystem.out.println() sağlayıcınıza bağlı olarak şunları yapabilirsiniz:

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());

Openjpa tabanlı uygulamamızda, bu parametreler parametreli bir sorgu için sorgunun bir parçası olarak gösterilmez.
timwaagh

1

Spring framework kullanıyorsanız. Application.properties dosyanızı aşağıdaki gibi değiştirin

#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

Spring Boot ile şunu ekleyin: spring.jpa.show-sql = application.properties. Bu, sorguyu gösterir ancak gerçek parametreler olmadan (her parametre yerine? Görürsünüz).


0

Keşifsel geliştirme sırasında ve SQL hata ayıklama günlüğünü denetlemek istediğim belirli yönteme odaklamak için, bu yöntemi aşağıdaki günlükçü ifadeleriyle süslüyorum:

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 çıktısı için EclipseLink (persistence.xml config):

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

-2

Persistence.xml adlı bir dosya var ve Ctrl + Shift + R tuşlarına basın ve onu bulun, sonra showSQL gibi bir şey yazılmış bir yer var.

Sadece doğru olarak koy

Sunucunun Hata Ayıklama modu olarak başlatılması gerekip gerekmediğinden emin değilim. Konsolda oluşturulan SQL'leri kontrol edin.


Bu sadece sql deyimi gösterir parametreleri göstermek için yeterli değil mi? parametreler için.
Ebuzer Taha KANAT

1
"ShowSQL gibi bir şey" cevap değildir. ve Ctrl + Üst Karakter + R? IDE hakkında bir varsayım yaptınız.
8bitjunkie
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.