Come stampare una stringa di query con valori di parametro quando si utilizza Hibernate


Risposte:


428

È necessario abilitare la registrazione per le seguenti categorie:

  • org.hibernate.SQL   - impostato per debugregistrare tutte le istruzioni DML SQL man mano che vengono eseguite
  • org.hibernate.type- impostato per traceregistrare tutti i parametri JDBC

Quindi una configurazione log4j potrebbe apparire come:

# logs the SQL statements
log4j.logger.org.hibernate.SQL=debug 

# Logs the JDBC parameters passed to a query
log4j.logger.org.hibernate.type=trace 

Il primo equivale alla proprietàhibernate.show_sql=true legacy , il secondo stampa i parametri associati tra le altre cose.

Un'altra soluzione (non basata su ibernazione) sarebbe quella di utilizzare un driver proxy JDBC come P6Spy .


11
Questo è utile Ma questo non mi mostra le vere query SQL.
Nicolas Barbulesco,

6
@Nicolas è vero, anche se immediatamente dopo la query invia i parametri associati.
Xtreme Biker,

2
Sto usando Grails 2.4.4 e ibisco 4. Cambiare la configurazione di log4j non ha funzionato per me ma p6spy ha funzionato!
Champ

11
In Hibernate 5 possiamo usare il org.hibernate.type.descriptor.sql.BasicBinderlogger. Abilitare il log in per org.hibernate.typestampare troppe informazioni inutili per me ...
csharpfolk

5
org.hibernate.typee org.hibernate.loader.hqlnon lavorare per me per mostrare i parametri
Dherik

75

Per comodità, ecco lo stesso esempio di configurazione per Logback (SLF4J)

<appender name="SQLROLLINGFILE">
 <File>/tmp/sql.log</File>
 <rollingPolicy>
  <FileNamePattern>logFile.%d{yyyy-MM-dd}.log</FileNamePattern>
 </rollingPolicy>
 <layout>
  <Pattern>%-4date | %msg %n</Pattern>
 </layout>
</appender>

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

<logger name="org.hibernate.type" additivity="false" >
 <level value="TRACE" />
 <appender-ref ref="SQLROLLINGFILE" />
</logger>

L'output nel tuo sql.log (esempio) è quindi simile al seguente:

2013-08-30 18:01:15,083 | update stepprovider set created_at=?, lastupdated_at=?, version=?, bundlelocation=?, category_id=?, customer_id=?, description=?, icon_file_id=?, name=?, shareStatus=?, spversion=?, status=?, title=?, type=?, num_used=? where id=?
2013-08-30 18:01:15,084 | binding parameter [1] as [TIMESTAMP] - 2012-07-11 09:57:32.0
2013-08-30 18:01:15,085 | binding parameter [2] as [TIMESTAMP] - Fri Aug 30 18:01:15 CEST 2013
2013-08-30 18:01:15,086 | binding parameter [3] as [INTEGER] -
2013-08-30 18:01:15,086 | binding parameter [4] as [VARCHAR] - com.mypackage.foo
2013-08-30 18:01:15,087 | binding parameter [5] as [VARCHAR] -
2013-08-30 18:01:15,087 | binding parameter [6] as [VARCHAR] -
2013-08-30 18:01:15,087 | binding parameter [7] as [VARCHAR] - TODO
2013-08-30 18:01:15,087 | binding parameter [8] as [VARCHAR] -
2013-08-30 18:01:15,088 | binding parameter [9] as [VARCHAR] - MatchingStep@com.mypackage.foo
2013-08-30 18:01:15,088 | binding parameter [10] as [VARCHAR] - PRIVATE
2013-08-30 18:01:15,088 | binding parameter [11] as [VARCHAR] - 1.0
2013-08-30 18:01:15,088 | binding parameter [12] as [VARCHAR] - 32
2013-08-30 18:01:15,088 | binding parameter [13] as [VARCHAR] - MatchingStep
2013-08-30 18:01:15,089 | binding parameter [14] as [VARCHAR] -
2013-08-30 18:01:15,089 | binding parameter [15] as [INTEGER] - 0
2013-08-30 18:01:15,089 | binding parameter [16] as [VARCHAR] - 053c2e65-5d51-4c09-85f3-2281a1024f64

2
Questo non risponde alla domanda dei PO.
ShadowGames,

33

Passare hibernate.cfg.xmla:

<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>

Includi log4j e le voci seguenti in "log4j.properties":

log4j.logger.org.hibernate=INFO, hb
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE

log4j.appender.hb=org.apache.log4j.ConsoleAppender
log4j.appender.hb.layout=org.apache.log4j.PatternLayout

Grazie, ha funzionato davvero bene per me. Tali impostazioni aggiungeranno alla query sql un parametro simile binding parameter [1] as [VARCHAR] - [1].
G. Ciardino,

28

In caso di utilizzo dell'avvio a molla, configura questo:

aplication.yml

logging:
  level:
    org.hibernate.SQL: DEBUG
    org.hibernate.type: TRACE

aplication.properties

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE

e niente di più.

HTH


20

Log4JDBC è una bella soluzione che stampa l' esatto SQL andando al database con i parametri in atto piuttosto che la risposta più popolare qui che non lo fa. Una grande comodità di ciò è che puoi copiare l'SQL direttamente sul tuo front-end DB ed eseguirlo così com'è.

http://log4jdbc.sourceforge.net/

https://code.google.com/p/log4jdbc-remix/

Quest'ultimo genera anche una rappresentazione tabellare dei risultati della query.

Output di esempio che mostra l'SQL generato con i parametri in atto insieme alla tabella del set di risultati dalla query:

5. insert into ENQUIRY_APPLICANT_DETAILS (ID, INCLUDED_IN_QUOTE, APPLICANT_ID, TERRITORY_ID, ENQUIRY_ID, ELIGIBLE_FOR_COVER) values (7, 1, 11, 1, 2, 0) 


10 Oct 2013 16:21:22 4953 [main] INFO  jdbc.resultsettable  - |---|--------|--------|-----------|----------|---------|-------|
10 Oct 2013 16:21:22 4953 [main] INFO  jdbc.resultsettable  - |ID |CREATED |DELETED |CODESET_ID |NAME      |POSITION |PREFIX |
10 Oct 2013 16:21:22 4953 [main] INFO  jdbc.resultsettable  - |---|--------|--------|-----------|----------|---------|-------|
10 Oct 2013 16:21:22 4953 [main] INFO  jdbc.resultsettable  - |2  |null    |null    |1          |Country 2 |1        |60     |
10 Oct 2013 16:21:22 4953 [main] INFO  jdbc.resultsettable  - |---|--------|--------|-----------|----------|---------|-------|

Aggiornamento 2016

Più recentemente sto usando log4jdbc-log4j2 ( https://code.google.com/archive/p/log4jdbc-log4j2/ ) con SLF4j e il logback. Le dipendenze Maven richieste per il mio set-up sono le seguenti:

<dependency>
    <groupId>org.bgee.log4jdbc-log4j2</groupId>
    <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
    <version>1.16</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>${logback.version}</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>$logback.version}</version>
</dependency>

Gli URL del driver e del DB sono quindi simili:

database.driver.class=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
database.url=jdbc:log4jdbc:hsqldb:mem:db_name #Hsql
#database.url=jdbc:log4jdbc:mysql://localhost:3306/db_name 

Il mio file di configurazione logback.xml è simile al seguente: questo genera tutte le istruzioni SQL con parametri più le tabelle dei risultati per tutte le query.

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

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <logger name="jdbc.audit" level="ERROR" />
    <logger name="jdbc.connection" level="ERROR" />
    <logger name="jdbc.sqltiming" level="ERROR" />
    <logger name="jdbc.resultset" level="ERROR" />

    <!-- UNCOMMENT THE BELOW TO HIDE THE RESULT SET TABLE OUTPUT -->
    <!--<logger name="jdbc.resultsettable" level="ERROR" /> -->

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

Alla fine, ho dovuto creare un file chiamato log4jdbc.log4j2.properties alla radice del percorso di classe, ad esempio src / test / resources o src / main / resources in un progetto Mevn. Questo file ha una riga che è la seguente:

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator

Quanto sopra dipenderà dalla tua libreria di registrazione. Consulta i documenti su https://code.google.com/archive/p/log4jdbc-log4j2 per ulteriori informazioni

Uscita campione:

10:44:29.400 [main] DEBUG jdbc.sqlonly -  org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70)
5. select memberrole0_.member_id as member_i2_12_0_, memberrole0_.id as id1_12_0_, memberrole0_.id 
as id1_12_1_, memberrole0_.member_id as member_i2_12_1_, memberrole0_.role_id as role_id3_12_1_, 
role1_.id as id1_17_2_, role1_.name as name2_17_2_ from member_roles memberrole0_ left outer 
join roles role1_ on memberrole0_.role_id=role1_.id where memberrole0_.member_id=104 

10:44:29.402 [main] INFO  jdbc.resultsettable - 
|----------|---|---|----------|--------|---|-----|
|member_id |id |id |member_id |role_id |id |name |
|----------|---|---|----------|--------|---|-----|
|----------|---|---|----------|--------|---|-----|

1
Ehi .... Sembra figo .... proprio quello che il medico ha ordinato per me :) ... ma supporta anche CLOB / BLOB ?? Inoltre, è possibile visualizzare solo la query e non il set di risultati. - Grazie :)
dev ray il

1
potresti darmi un esempio di configurazione come farlo?
grep,

In realtà, quest'ultimo genera una rappresentazione tablare dei risultati della query ... vale a dire uno ha bisogno di log4jdbc-remix per quella bella funzionalità.
Meriton,

Questa soluzione era la migliore per la mia situazione in cui avevo bisogno di vedere i valori dei numeri di riga generati da Hibernate per i set di risultati di paginazione. La registrazione della traccia mostra solo i valori dei parametri di query.
Oliver Hernandez,

@Alan Hay fa anche questo log delle query native?
Sayantan,

9

È possibile aggiungere righe di categoria a log4j.xml:

<category name="org.hibernate.type">
    <priority value="TRACE"/>
</category>

e aggiungi le proprietà di ibernazione:

<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>

7

aggiungi le seguenti proprietà e valori alla tua configurazione log4j o logback:

org.hibernate.sql=DEBUG
org.hibernate.type.descriptor.sql.BasicBinder=TRACE

5
La org.hibernate.type.descriptor.sql.BasicBindercategoria non include tutti i parametri, ad esempio i tipi di enum. Quindi, se vuoi tutto, hai davvero bisogno TRACEdi tutto il org.hibernate.typegruppo.
seanf,

Per me funziona in Hibernate 4.3! Inoltre, non vorrei tracciare l'intero org.hibernate.type, perché è un risultato eccessivo. Nella maggior parte dei casi, questa soluzione farà.
cslotty,

Si noti che org.hibernate.type.descriptor.sql.BasicExtractor registra i set di risultati. Quindi avere voci di grandi dimensioni può persino arrestare in modo anomalo l'applicazione quando si accede alla console in Eclipse, e suppongo che non sia l'ideale per accedere al file. Ecco perché preferisco questa soluzione, funziona anche in Hibernate 3. Per coloro che sono interessati ai tipi di enum, prova la classe esatta che li registra quando org.hibernate.type = TRACE. Quindi impostare org.hibernate.type.xyz.TheClassThatLogsEnumParams = TRACE.
Géza,

7

Puoi farlo usando il proxy dell'origine dati , come ho descritto in questo post .

Supponendo che l'applicazione si aspetti un dataSourcebean (ad esempio tramite @Resource), ecco come è possibile configurare datasource-proxy:

<bean id="actualDataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init"
  destroy-method="close">
    <property name="className" value="bitronix.tm.resource.jdbc.lrc.LrcXADataSource"/>
    <property name="uniqueName" value="actualDataSource"/>
    <property name="minPoolSize" value="0"/>
    <property name="maxPoolSize" value="5"/>
    <property name="allowLocalTransactions" value="false" />
    <property name="driverProperties">
        <props>
            <prop key="user">${jdbc.username}</prop>
            <prop key="password">${jdbc.password}</prop>
            <prop key="url">${jdbc.url}</prop>
            <prop key="driverClassName">${jdbc.driverClassName}</prop>
        </props>
    </property>
</bean>

<bean id="proxyDataSource" class="net.ttddyy.dsproxy.support.ProxyDataSource">
    <property name="dataSource" ref="testDataSource"/>
    <property name="listener">
        <bean class="net.ttddyy.dsproxy.listener.ChainListener">
            <property name="listeners">
                <list>
                    <bean class="net.ttddyy.dsproxy.listener.CommonsQueryLoggingListener">
                        <property name="logLevel" value="INFO"/>
                    </bean>
                    <bean class="net.ttddyy.dsproxy.listener.DataSourceQueryCountListener"/>
                </list>
            </property>
        </bean>
    </property>
</bean>

<alias name="proxyDataSource" alias="dataSource"/>

Ora l'output di Hibernate vs proxy origine dati:

INFO  [main]: n.t.d.l.CommonsQueryLoggingListener - Name:, Time:1, Num:1, Query:{[select company0_.id as id1_6_, company0_.name as name2_6_ from Company company0_][]}
INFO  [main]: n.t.d.l.CommonsQueryLoggingListener - Name:, Time:0, Num:1, Query:{[insert into WarehouseProductInfo (id, quantity) values (default, ?)][19]}
INFO  [main]: n.t.d.l.CommonsQueryLoggingListener - Name:, Time:0, Num:1, Query:{[insert into Product (id, code, company_id, importer_id, name, version) values (default, ?, ?, ?, ?, ?)][phoneCode,1,-5,Phone,0]}

Le datasource-proxyquery contengono valori di parametro e puoi persino aggiungere intercettori di istruzioni JDBC personalizzati in modo da poter rilevare i problemi di query N + 1 direttamente dai test di integrazione .


5

attiva il org.hibernate.typeLogger per vedere come i parametri effettivi sono associati ai punti interrogativi.


4

<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="logs/system.log" />
    <param name="Append" value="true" />
    <param name="ImmediateFlush" value="true" />
    <param name="MaxFileSize" value="200MB" />
    <param name="MaxBackupIndex" value="100" />

    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d %d{Z} [%t] %-5p (%F:%L) - %m%n" />
    </layout>
</appender>

<appender name="journaldev-hibernate" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="logs/project.log" />
    <param name="Append" value="true" />
    <param name="ImmediateFlush" value="true" />
    <param name="MaxFileSize" value="200MB" />
    <param name="MaxBackupIndex" value="50" />

    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d %d{Z} [%t] %-5p (%F:%L) - %m%n" />
    </layout>
</appender>

<logger name="com.journaldev.hibernate" additivity="false">
    <level value="DEBUG" />
    <appender-ref ref="journaldev-hibernate" />
</logger>

<logger name="org.hibernate" additivity="false">
    <level value="INFO" />
    <appender-ref ref="FILE" />
</logger>

<logger name="org.hibernate.type" additivity="false">
    <level value="TRACE" />
    <appender-ref ref="FILE" />
</logger>

<root>
    <priority value="INFO"></priority>
    <appender-ref ref="FILE" />
</root>


3

La soluzione è corretta ma registra anche tutti i binding per gli oggetti risultato. Per evitare ciò, è possibile creare un appender separato e abilitare il filtro, ad esempio:

<!-- A time/date based rolling appender -->
<appender name="FILE_HIBERNATE" class="org.jboss.logging.appender.DailyRollingFileAppender">
    <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
    <param name="File" value="${jboss.server.log.dir}/hiber.log"/>
    <param name="Append" value="false"/>
    <param name="Threshold" value="TRACE"/>
    <!-- Rollover at midnight each day -->
    <param name="DatePattern" value="'.'yyyy-MM-dd"/>

    <layout class="org.apache.log4j.PatternLayout">
        <!-- The default pattern: Date Priority [Category] Message\n -->
        <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
    </layout>

    <filter class="org.apache.log4j.varia.StringMatchFilter">
        <param name="StringToMatch" value="bind" />
        <param name="AcceptOnMatch" value="true" />
    </filter>
    <filter class="org.apache.log4j.varia.StringMatchFilter">
        <param name="StringToMatch" value="select" />
        <param name="AcceptOnMatch" value="true" />
    </filter>  
    <filter class="org.apache.log4j.varia.DenyAllFilter"/>
</appender> 

<category name="org.hibernate.type">
  <priority value="TRACE"/>
</category>

<logger name="org.hibernate.type">
   <level value="TRACE"/> 
   <appender-ref ref="FILE_HIBERNATE"/>
</logger>

<logger name="org.hibernate.SQL">
   <level value="TRACE"/> 
   <appender-ref ref="FILE_HIBERNATE"/>
</logger>

3
**If you want hibernate to print generated sql queries with real values instead of question marks.**
**add following entry in hibernate.cfg.xml/hibernate.properties:**
show_sql=true
format_sql=true
use_sql_comments=true

**And add following entry in log4j.properties :**
log4j.logger.org.hibernate=INFO, hb
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE
log4j.appender.hb=org.apache.log4j.ConsoleAppender
log4j.appender.hb.layout=org.apache.log4j.PatternLayout

Ehi, le righe precedenti single31 devono essere aggiunte nel file di configurazione dell'ibernazione, quindi funzionerà sicuramente. Pubblico sempre cose che ho fatto praticamente.
Vijay Bhatt,

3

Questa risposta è una piccola variazione per la domanda. A volte, abbiamo solo bisogno di sql solo per scopi di debug in fase di esecuzione. In tal caso, esiste un modo più semplice, utilizzando il debug sugli editor.

  • Inserisci un punto di interruzione su org.hibernate.loader.Loader.loadEntityBatch (o vai nello stack fino a lì);
  • Quando l'esecuzione è sospesa, guarda il valore della variabile this.sql;

Questo è per ibernazione 3. Non sono sicuro che questo lavoro su altre versioni.


3

Il driver mysql jdbc ha già fornito un comodo per soddisfare questo requisito, è necessario almeno avere la versione jar> = mysql-connect-jar-5.1.6.jar

passaggio 1: [configura jdbc.url per aggiungere il logger e la registrazione personalizzata]

    jdbc.url=jdbc:mysql://host:port/your_db?logger=com.mysql.jdbc.log.Slf4JLogger&profileSQL=true&profilerEventHandler=com.xxx.CustomLoggingProfilerEventHandler

ora utilizza la registrazione slf4j, se la registrazione predefinita è log4j, è necessario aggiungere dipendenze slf4j-api, slf4j-log4j12 per utilizzare la registrazione slf4j

passaggio 2: [scrivi la tua registrazione personalizzata]

package com.xxx;
import java.sql.SQLException;
import java.util.Properties;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.log.Log;

public class CustomLoggingProfilerEventHandler implements ProfilerEventHandler {
    private Log log;

    public LoggingProfilerEventHandler() {
    }

    public void consumeEvent(ProfilerEvent evt) {
            /**
             * you can only print the sql as        this.log.logInfo(evt.getMessage())
             * you can adjust your sql print log level with: DEBUG,INFO
             * you can also handle the message to meet your requirement
             */ 
            this.log.logInfo(evt);
    }

    public void destroy() {
        this.log = null;
    }

    public void init(Connection conn, Properties props) throws SQLException {
        this.log = conn.getLog();
    }

}

2

Mi piace questo per log4j:

log4j.logger.org.hibernate.SQL=trace
log4j.logger.org.hibernate.engine.query=trace
log4j.logger.org.hibernate.type=trace
log4j.logger.org.hibernate.jdbc=trace
log4j.logger.org.hibernate.type.descriptor.sql.BasicExtractor=error 
log4j.logger.org.hibernate.type.CollectionType=error 

Ehi, è carino. Ma penso che qui le domande siano stampate con il? seguito con i valori dei parametri. Dal momento che ho un numero infinito di query, ho bisogno di qualcosa che posso semplicemente copiare e incollare sull'editor sql e verranno eseguite. C'è un modo in cui posso farlo usando questo approccio. Non sono così entusiasta di scegliere librerie di terze parti. Grazie :)
dev ray,

Grazie. Speravo di non dover utilizzare soluzioni di terze parti e di ibernare direttamente, ma immagino di non avere altra scelta.
dev ray

2

La registrazione funziona ma non esattamente quello che vuoi o volevo qualche tempo fa, ma P6Spy funziona perfettamente ,

ecco il semplice tutorial per implementare anche il tutorial MKYONG per P6Spy .

per me ha funzionato come un fascino.

  1. Scarica la libreria P6Spy

Ottieni il "p6spy-install.jar"

  1. Estrai

Estrai il p6spy-install.jarfile, cerca p6spy.jarespy.properties

  1. Aggiungi dipendenza dalla libreria

Aggiungi p6spy.jarnella tua libreria del progetto la dipendenza

  1. Modifica il file delle proprietà P6Spy

Modifica il tuo file di configurazione del database. È necessario sostituire il driver JDBC esistente con il driver JDBC P6Spy -com.p6spy.engine.spy.P6SpyDriver

L'originale è il driver MySQL JDBC - com.mysql.jdbc.Driver

<session-factory>
  <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.password">password</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mkyong</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="show_sql">true</property>
</session-factory>

Modificato in driver JDBC P6Spy - com.p6spy.engine.spy.P6SpyDriver

<session-factory>
  <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
  <property name="hibernate.connection.driver_class">com.p6spy.engine.spy.P6SpyDriver
  </property>
  <property name="hibernate.connection.password">password</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mkyong</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="show_sql">true</property>
</session-factory>
  1. Modifica il file delle proprietà P6Spy Modifica il file delle proprietà P6Spy -spy.properties

Sostituisci real drivercon il tuo driver MySQL JDBC esistente

realdriver=com.mysql.jdbc.Driver

#specifies another driver to use
realdriver2=
#specifies a third driver to use
realdriver3=

Modifica la posizione del file di registro Modifica la posizione del file di registro nella proprietà del file di registro, tutte le istruzioni SQL accederanno a questo file.

finestre

logfile     = c:/spy.log

* nix

logfile     = /srv/log/spy.log
  1. Copia “spy.properties”nel percorso di classe del progetto

Copia “spy.properties”nella cartella principale del tuo progetto, assicurati che il tuo progetto sia in grado di individuare "spy.properties", altrimenti verrà richiesta l' “spy.properties”eccezione del file non trovato.


Questo è stato il percorso più semplice per me nella mia applicazione Spring Boot, dove stavo provando a registrare SQL generato da un test unitario. Ho aggiunto una dipendenza di prova a Gradle (testCompile 'p6spy: p6spy: 3.8.5'), modificato application.yml per impostare spring.datasource.url = jdbc: p6spy: h2: mem: testdb e spring.datasource.driver-class- name = com.p6spy.engine.spy.P6SpyDriver e quindi aggiunto spy.properties con realdriver = org.h2.Driver e file di registro impostati sul mio percorso preferito. È stato facile estrarre l'intero SQL dal file di registro risultante. L'unico inconveniente era che H2 non gradiva il formato di data / ora generato.
Ken Pronovici,

2

<appender name="console" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" 
      value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
    </layout>
</appender>

<logger name="org.hibernate" additivity="false">
    <level value="INFO" />
    <appender-ref ref="console" />
</logger>

<logger name="org.hibernate.type" additivity="false">
    <level value="TRACE" />
    <appender-ref ref="console" />
</logger>


In che modo questo si collega alla domanda?
hotzst

2

Usando Hibernate 4 e slf4j / log4j2, ho provato ad aggiungere quanto segue nella mia configurazione log4j2.xml:

<Logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="trace" additivity="false"> 
    <AppenderRef ref="Console"/> 
</Logger> 
<Logger name="org.hibernate.type.EnumType" level="trace" additivity="false"> 
    <AppenderRef ref="Console"/>
</Logger>

Ma senza successo.

Ho scoperto attraverso questo thread che il framework di registrazione jboss usato da ibernazione doveva essere configurato per accedere tramite slf4j. Ho aggiunto il seguente argomento agli argomenti VM dell'applicazione:

-Dorg.jboss.logging.provider=slf4j

E ha funzionato come un fascino.


2

Ecco cosa ha funzionato per me, impostato sotto la proprietà nel file log4j.file:

log4j.logger.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

Sospensione delle impostazioni delle proprietà:

hibernate.show_sql=true

2

per lo sviluppo con Wildfly (standalone.xml), aggiungi quei logger:

<logger category="org.hibernate.SQL">
   <level name="DEBUG"/>
</logger>
<logger category="org.hibernate.type.descriptor.sql">
   <level name="TRACE"/>
</logger>

1

se si utilizza l'ibernazione 3.2.xx, utilizzare

log4j.logger.org.hibernate.SQL=trace

invece di

log4j.logger.org.hibernate.SQL=debug 

1

Puoi registrarlo:

net.sf.hibernate.hql.QueryTranslator

Esempio di output:

2013-10-31 14:56:19,029 DEBUG [net.sf.hibernate.hql.QueryTranslator] HQL: select noti.id, noti.idmicrosite, noti.fcaducidad, noti.fpublicacion, noti.tipo, noti.imagen, noti.visible, trad.titulo, trad.subtitulo, trad.laurl, trad.urlnom, trad.fuente, trad.texto  from org.ibit.rol.sac.micromodel.Noticia noti join noti.traducciones trad where index(trad)='ca' and noti.visible='S' and noti.idmicrosite=985 and noti.tipo=3446

2013-10-31 14:56:19,029 DEBUG [net.sf.hibernate.hql.QueryTranslator] SQL: select noticia0_.NOT_CODI as x0_0_, noticia0_.NOT_MICCOD as x1_0_, noticia0_.NOT_CADUCA as x2_0_, noticia0_.NOT_PUBLIC as x3_0_, noticia0_.NOT_TIPO as x4_0_, noticia0_.NOT_IMAGEN as x5_0_, noticia0_.NOT_VISIB as x6_0_, traduccion1_.NID_TITULO as x7_0_, traduccion1_.NID_SUBTIT as x8_0_, traduccion1_.NID_URL as x9_0_, traduccion1_.NID_URLNOM as x10_0_, traduccion1_.NID_FUENTE as x11_0_, traduccion1_.NID_TEXTO as x12_0_ from GUS_NOTICS noticia0_ inner join GUS_NOTIDI traduccion1_ on noticia0_.NOT_CODI=traduccion1_.NID_NOTCOD where (traduccion1_.NID_CODIDI='ca' )and(noticia0_.NOT_VISIB='S' )and(noticia0_.NOT_MICCOD=985 )and(noticia0_.NOT_TIPO=3446 )

Ehi ... non riesco a trovare alcun esempio di questo approccio. Potresti fornire riferimenti / esempi / tutorial. Ed è sempre lo stesso con le ultime versioni o ibernazione / log4j o è diventato un org.hibernate.QueryTranslator o qualcosa del genere. Grazie
dev ray il

Ehi ... ci ho provato, ma questo non sembra funzionare con il salvataggio o l'aggiornamento. Immagino che funzioni solo con query selezionate, in cui entra in gioco la traduzione da hql a sql
dev ray,

1

Il plugin Log4Jdbc sarebbe il migliore per le tue esigenze. Mostra seguente-

1. Complete SQL query being hit to the db
2. Parameter values being passed to the query
3. Execution time taken by each query

Fare riferimento al collegamento seguente per configurare Log4Jdbc-

https://code.google.com/p/log4jdbc/

1

Usa Wireshark o qualcosa di simile:

Nessuna delle risposte sopra menzionate stamperà sql con parametri correttamente o è una seccatura. Ho raggiunto questo obiettivo utilizzando WireShark , che acquisisce tutti i comandi / sql inviati dall'applicazione a Oracle / Mysql ecc. Con le query.


2
Log4JDBC lo farà. Vedi sopra.
Alan Hay,

1

Tutte le risposte qui sono utili, ma se stai usando un XML di contesto di applicazione Spring per impostare il factory di sessione, l'impostazione della variabile di livello SQL log4j ti fa solo parte del percorso, devi anche impostare la variabile hibernate.show_sql nel contesto dell'app stesso per far sì che Hibernate inizi effettivamente a mostrare i valori.

ApplicationContext.xml ha:

<property name="hibernateProperties">
            <value>
            hibernate.jdbc.batch_size=25
            ... <!-- Other parameter values here -->
            hibernate.show_sql=true
            </value>
 </property>

E il tuo file log4j ha bisogno

log4j.logger.org.hibernate.SQL=DEBUG

1

In Java:

Trasforma la tua query in TypedQuery se si tratta di CriteriaQuery (javax.persistence).

Poi:

query.unwrap (org.hibernate.Query.class) .getQueryString ();


1
Grazie, stampa la query, ma non i parametri che ha usato, c'è un modo per stampare anche i parametri?
Liz Lamperouge,

0

Hibernate mostra la query e i relativi valori dei parametri in diverse righe.

Se si utilizza application.properties in Spring Boot e si può usare il parametro evidenziato in basso in application.properties.

  1. org.hibernate.SQL mostrerà le query

    logging.level.org.hibernate.SQL = DEBUG

  2. org.hibernate.type mostrerà tutti i valori dei parametri, che verranno mappati con query di selezione, inserimento e aggiornamento. logging.level.org.hibernate.type = TRACE

    • org.hibernate.type.EnumType mostrerà il valore del parametro del tipo enum

      logging.level.org.hibernate.type.EnumType = TRACE

      esempio ::

      2018-06-14 11:06:28,217 TRACE [main] [EnumType.java : 321] Binding [active] to parameter: [1]
    • sql.BasicBinder mostrerà il valore di parametro intero, varchar, tipo booleano

      logging.level.org.hibernate.type.descriptor.sql.BasicBinder = TRACE

      esempio ::

      • 14/06/2018 11: 28: 29.750 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] parametro di binding [1] come [BOOLEAN] - [true]
      • 14/06/2018 11: 28: 29.751 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] parametro di associazione [2] come [INTEGER] - [1]
      • 14/06/2018 11: 28: 29.752 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] parametro di associazione [3] come [VARCHAR] - [pubblico]

1
Anche questo non mostra i valori di limite e offset nelle query.
T3rm1,

0

La soluzione più semplice per me è implementare una stringa normale Sostituisci per sostituire gli input dei parametri con i valori dei parametri (trattando tutti i parametri come stringa, per semplicità):

 String debugedSql = sql;
 //then, for each named parameter
     debugedSql = debugedSql.replaceAll(":"+key, "'"+value.toString()+"'");
 //and finnaly
 println(debugedSql);

o qualcosa di simile per i parametri posizionali (?).
Prenditi cura di valori nulli e tipi di valore specifici come la data, se vuoi che sia registrato un sql pronto per la corsa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.