Cómo imprimir una cadena de consulta con valores de parámetros cuando se usa Hibernate


Respuestas:


429

Debe habilitar el registro para las siguientes categorías:

  • org.hibernate.SQL   - configurado para debugregistrar todas las sentencias SQL DML a medida que se ejecutan
  • org.hibernate.type- configurado para traceregistrar todos los parámetros JDBC

Entonces una configuración log4j podría verse así:

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

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

El primero es equivalente a la propiedadhibernate.show_sql=true heredada , el segundo imprime los parámetros vinculados, entre otras cosas.

Otra solución (no basada en hibernación) sería utilizar un controlador proxy JDBC como P6Spy .


11
Esto es útil. Pero esto no me muestra las consultas SQL reales.
Nicolas Barbulesco

66
@Nicolas es cierto, sin embargo, inmediatamente después de la consulta, muestra los parámetros enlazados.
Xtreme Biker

2
Estoy usando Grails 2.4.4 e Hibernate 4. Cambiar la configuración de log4j no funcionó para mí, ¡pero p6spy funcionó!
Campeón el

11
En Hibernate 5 podemos usar org.hibernate.type.descriptor.sql.BasicBinderlogger. Habilitando el inicio de sesión org.hibernate.type
imprimí

55
org.hibernate.typey org.hibernate.loader.hqlno funciona para mí mostrar los parámetros
Dherik

75

Solo por conveniencia, este es el mismo ejemplo de configuración para 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>

El resultado en su sql.log (ejemplo) se ve así:

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
Esto no responde a la pregunta de los OP.
ShadowGames

33

Cambiar hibernate.cfg.xmla:

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

Incluya las entradas log4j y siguientes en "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

Gracias, me ha funcionado muy bien. Esas configuraciones agregarán bajo la consulta sql un parámetro como binding parameter [1] as [VARCHAR] - [1].
G. Ciardini

29

En caso de que se esté usando el arranque de primavera, solo configure esto:

aplication.yml

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

aplicacion.properties

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

y nada más.

HTH


21

Log4JDBC es una buena solución que imprime el SQL exacto que va a la base de datos con los parámetros establecidos en lugar de la respuesta más popular aquí que no hace esto. Una de las principales ventajas de esto es que puede copiar el SQL directamente en el front-end de su base de datos y ejecutarlo tal cual.

http://log4jdbc.sourceforge.net/

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

Este último también genera una representación tabular de los resultados de la consulta.

Salida de muestra que muestra el SQL generado con parámetros en su lugar junto con la tabla de conjunto de resultados de la consulta:

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  - |---|--------|--------|-----------|----------|---------|-------|

Actualización 2016

Más recientemente, he estado usando log4jdbc-log4j2 ( https://code.google.com/archive/p/log4jdbc-log4j2/ ) con SLF4j y logback. Las dependencias de Maven requeridas para mi configuración son las siguientes:

<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>

El controlador y las URL de DB se ven así:

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 

Mi archivo de configuración logback.xml tiene el siguiente aspecto: genera todas las instrucciones SQL con parámetros más las tablas de conjunto de resultados para todas las consultas.

<?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>

Finalmente, tuve que crear un archivo llamado log4jdbc.log4j2.properties en la raíz del classpath, por ejemplo, src / test / resources o src / main / resources en un proyecto Mevn. Este archivo tiene una línea que es la siguiente:

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

Lo anterior dependerá de su biblioteca de registro. Consulte los documentos en https://code.google.com/archive/p/log4jdbc-log4j2 para obtener más información.

Salida de muestra:

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
Hola ... Esto parece genial ... justo lo que me recetó el médico :) ... pero ¿también es compatible con CLOB / BLOB? Además, ¿es posible mostrar solo la consulta y no el conjunto de resultados? - Gracias :)
dev ray

1
¿podría darme un ejemplo de configuración cómo hacerlo?
grep

En realidad, este último genera una representación tabular de los resultados de la consulta ... es decir, uno necesita log4jdbc-remix para esa característica agradable.
meriton

Esta solución fue la mejor para mi situación en la que necesitaba ver los valores de número de fila que Hibernate genera para los conjuntos de resultados de paginación. El registro de seguimiento solo muestra los valores de los parámetros de consulta.
Oliver Hernández el

@ Alan Hay, ¿esto también registra consultas nativas?
Sayantan

9

Puede agregar líneas de categoría a log4j.xml:

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

y agregue propiedades de hibernación:

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

7

agregue las siguientes propiedades y valores a su configuración log4j o logback:

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

55
La org.hibernate.type.descriptor.sql.BasicBindercategoría no incluye todos los parámetros, por ejemplo, tipos de enumeración. Entonces, si quieres todo, realmente necesitas TRACEpara todo el org.hibernate.typegrupo.
seanf

¡Para mí funciona en Hibernate 4.3! Además, no RASTREARÍA el org.hibernate.type completo, porque eso es demasiada salida. En la mayoría de los casos, esta solución servirá.
cslotty

Tenga en cuenta que org.hibernate.type.descriptor.sql.BasicExtractor registra los conjuntos de resultados. Por lo tanto, tener una entrada de gran tamaño puede incluso bloquear la aplicación al iniciar sesión en la consola en Eclipse, y supongo que tampoco es ideal para iniciar sesión en el archivo. Es por eso que prefiero esta solución, también funciona en Hibernate 3. Para aquellos que estén interesados ​​en los tipos de enumeración, pruebe la clase exacta que los registra cuando org.hibernate.type = TRACE. Luego establezca org.hibernate.type.xyz.TheClassThatLogsEnumParams = TRACE.
Géza

7

Puede hacerlo utilizando el proxy de origen de datos , como describí en esta publicación .

Suponiendo que su aplicación espera un dataSourcebean (por ejemplo, vía @Resource), así es como puede configurar 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"/>

Ahora la salida de Hibernate vs datasource-proxy:

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]}

los datasource-proxy consultas contienen valores de parámetros e incluso puede agregar interceptores de sentencias JDBC personalizados para que pueda detectar problemas de consulta N + 1 directamente desde sus pruebas de integración .


5

encienda el org.hibernate.typeregistrador para ver cómo se unen los parámetros reales a los signos de interrogación.


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 solución es correcta, pero también registra todos los enlaces para los objetos de resultado. Para evitar esto, es posible crear un apéndice separado y habilitar el filtrado, por ejemplo:

<!-- 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

Hey single31 líneas anteriores tiene que agregarse en su archivo de configuración de hibernación y definitivamente funcionará Siempre publico cosas que he hecho prácticamente.
Vijay Bhatt

3

Esta respuesta es una pequeña variación para la pregunta. A veces, solo necesitamos el sql solo para fines de depuración en tiempo de ejecución. En ese caso, hay una manera más fácil, mediante la depuración en los editores.

  • Ponga un punto de interrupción en org.hibernate.loader.Loader.loadEntityBatch (o navegue en la pila hasta allí);
  • Cuando se suspende la ejecución, mire el valor de la variable this.sql;

Esto es para hibernar 3. No estoy seguro de que esto funcione en otras versiones.


3

El controlador mysql jdbc ya ha proporcionado un conveniente para cumplir con este requisito, al menos debe tener la versión jar> = mysql-connect-jar-5.1.6.jar

Paso 1: [configure su jdbc.url para agregar un registrador y un registro personalizado]

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

ahora, está usando el registro slf4j, si su registro predeterminado es log4j, debe agregar las dependencias slf4j-api, slf4j-log4j12 para usar el registro slf4j

Paso 2: [escribe tu registro personalizado]

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

Me gusta esto para 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 

Oye, esto es bueno. Pero creo que aquí las consultas se imprimen con el? seguido con los valores de los parámetros. Como tengo infinitas consultas, necesito algo que pueda copiar y pegar en el editor de SQL y se ejecutarán. ¿Hay alguna manera de hacerlo con este enfoque? No estoy tan interesado en ir a bibliotecas de terceros. Gracias :)
dev ray

Gracias. Esperaba no tener que usar soluciones de terceros e hibernar directamente, pero supongo que no tengo otra opción.
dev ray

2

El registro funciona pero no exactamente lo que deseaba o quería hace algún tiempo, pero P6Spy funciona perfectamente ,

Aquí está el tutorial simple para implementar también el tutorial MKYONG para P6Spy .

para mí funcionó a las mil maravillas.

  1. Descargar la biblioteca P6Spy

Obtenga el "p6spy-install.jar"

  1. Extraelo

Extraiga el p6spy-install.jararchivo, busque p6spy.jaryspy.properties

  1. Agregar dependencia de biblioteca

Agregue p6spy.jara su biblioteca de proyectos la dependencia

  1. Modificar el archivo de propiedades P6Spy

Modifique el archivo de configuración de su base de datos. Debe reemplazar su controlador JDBC existente con el controlador P6Spy JDBC:com.p6spy.engine.spy.P6SpyDriver

El original es el controlador 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>

Lo cambió al controlador 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. Modificar el archivo de propiedades P6Spy Modificar el archivo de propiedades P6Spy -spy.properties

Reemplace el real drivercon su controlador JDBC MySQL existente

realdriver=com.mysql.jdbc.Driver

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

Cambie la ubicación del archivo de registro Cambie la ubicación del archivo de registro en la propiedad del archivo de registro, todas las instrucciones SQL iniciarán sesión en este archivo.

Ventanas

logfile     = c:/spy.log

*nada

logfile     = /srv/log/spy.log
  1. Copiar “spy.properties”al proyecto classpath

Copie “spy.properties”a la carpeta raíz de su proyecto, asegúrese de que su proyecto pueda localizar "spy.properties", de lo contrario, solicitará “spy.properties”una excepción de archivo no encontrado.


Este fue el camino más fácil para mí en mi aplicación Spring Boot, donde estaba tratando de registrar el SQL generado a partir de una prueba unitaria. Agregué una dependencia de prueba a Gradle (testCompile 'p6spy: p6spy: 3.8.5'), ajusté application.yml para establecer spring.datasource.url = jdbc: p6spy: h2: mem: testdb y spring.datasource.driver-class- name = com.p6spy.engine.spy.P6SpyDriver, y luego agregué spy.properties con realdriver = org.h2.Driver y archivo de registro establecido en mi ruta preferida. Fue fácil extraer el SQL completo del archivo de registro resultante. El único inconveniente fue que a H2 no le gustó el formato de marca de tiempo generado.
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>


¿Cómo se relaciona esto con la pregunta?
hotzst

2

Usando Hibernate 4 y slf4j / log4j2, intenté agregar lo siguiente en mi configuración 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>

Pero sin éxito.

Descubrí a través de este hilo que el marco jboss-logging utilizado por hibernate necesitaba ser configurado para iniciar sesión a través de slf4j. Agregué el siguiente argumento a los argumentos de VM de la aplicación:

-Dorg.jboss.logging.provider=slf4j

Y funcionó como un encanto.


2

Esto es lo que funcionó para mí, establecer debajo de la propiedad en el archivo log4j:

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

Configuración de propiedades de hibernación:

hibernate.show_sql=true

2

para el desarrollo con Wildfly (standalone.xml), agregue esos registradores:

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

1

si está utilizando hibernate 3.2.xx use

log4j.logger.org.hibernate.SQL=trace

en vez de

log4j.logger.org.hibernate.SQL=debug 

1

Puedes registrar esto:

net.sf.hibernate.hql.QueryTranslator

Ejemplo de salida:

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 )

Oye ... no puedo encontrar ningún ejemplo de este enfoque. ¿Podría proporcionar alguna referencia / ejemplos / tutoriales? Y sigue siendo lo mismo con las últimas versiones o hibernate / log4j o se ha convertido en algún org.hibernate.QueryTranslator o algo así. Gracias
dev ray

Hola ... probé esto, pero parece que esto no funciona con guardar o actualizar. Supongo que solo funciona para consultas seleccionadas, donde entra en juego la traducción de hql a sql
dev ray

1

El complemento Log4Jdbc sería el mejor para su requerimiento. Muestra siguiente-

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

Consulte el siguiente enlace para configurar Log4Jdbc-

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

1

Usa Wireshark o algo similar:

Ninguna de las respuestas mencionadas anteriormente imprimirá sql con parámetros correctamente o es una molestia. Lo logré usando WireShark , que captura todos los sql / comandos que se envían desde la aplicación a Oracle / Mysql, etc. con las consultas.


2
Log4JDBC lo hará. Véase más arriba.
Alan Hay

1

Todas las respuestas aquí son útiles, pero si está utilizando un XML de contexto de aplicación Spring para configurar su fábrica de sesiones, establecer la variable de nivel log4j SQL solo lo ayuda a llegar allí, también debe configurar la variable hibernate.show_sql en el contexto de la aplicación para que Hibernate comience a mostrar los valores.

ApplicationContext.xml tiene:

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

Y tu archivo log4j necesita

log4j.logger.org.hibernate.SQL=DEBUG

1

En Java:

Transforme su consulta en TypedQuery si es un CriteriaQuery (javax.persistence).

Entonces:

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


1
Gracias, imprime la consulta, pero no los parámetros que utilizó, ¿hay una manera de imprimir los parámetros también?
Liz Lamperouge

0

Hibernate muestra la consulta y sus valores de parámetros en diferentes líneas.

Si está utilizando application.properties en el arranque de primavera y puede usar el parámetro resaltado a continuación en application.properties.

  1. org.hibernate.SQL mostrará consultas

    logging.level.org.hibernate.SQL = DEBUG

  2. org.hibernate.type mostrará todos los valores de los parámetros, que se asignarán con consultas de selección, inserción y actualización. logging.level.org.hibernate.type = TRACE

    • org.hibernate.type.EnumType mostrará el valor del parámetro de tipo enum

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

      ejemplo ::

      2018-06-14 11:06:28,217 TRACE [main] [EnumType.java : 321] Binding [active] to parameter: [1]
    • sql.BasicBinder mostrará un valor de parámetro de tipo entero, varchar y booleano

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

      ejemplo ::

      • 2018-06-14 11: 28: 29,750 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] parámetro de enlace [1] como [BOOLEAN] - [true]
      • 2018-06-14 11: 28: 29,751 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] parámetro de enlace [2] como [INTEGER] - [1]
      • 2018-06-14 11: 28: 29,752 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] parámetro de enlace [3] como [VARCHAR] - [public]

1
Incluso esto no muestra los valores de límite y compensación en las consultas.
T3rm1

0

La solución más simple para mí es implementar un stringReplace regular para reemplazar las entradas de parámetros con valores de parámetros (tratando todos los parámetros como string, por simplicidad):

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

o algo similar para los parámetros posicionales (?).
Tenga cuidado con los valores nulos y los tipos de valores específicos como la fecha, si desea que se registre un sql listo para la ejecución.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.