É possível no Hibernate imprimir consultas SQL geradas com valores reais em vez de pontos de interrogação?
Como você sugeriria imprimir consultas com valores reais, se isso não for possível com a API do Hibernate?
É possível no Hibernate imprimir consultas SQL geradas com valores reais em vez de pontos de interrogação?
Como você sugeriria imprimir consultas com valores reais, se isso não for possível com a API do Hibernate?
Respostas:
Você precisa habilitar o log para as seguintes categorias:
org.hibernate.SQL
- definido como debug
para registrar todas as instruções SQL DML à medida que são executadasorg.hibernate.type
- configure para trace
registrar todos os parâmetros JDBCPortanto, uma configuração do log4j pode se parecer com:
# logs the SQL statements
log4j.logger.org.hibernate.SQL=debug
# Logs the JDBC parameters passed to a query
log4j.logger.org.hibernate.type=trace
O primeiro é equivalente à propriedadehibernate.show_sql=true
herdada , o segundo imprime os parâmetros vinculados entre outras coisas.
Outra solução (não baseada em hibernação) seria usar um driver proxy JDBC como o P6Spy .
org.hibernate.type.descriptor.sql.BasicBinder
logger. A ativação do logon org.hibernate.type
imprimiu muitas informações inúteis para mim ...
org.hibernate.type
e org.hibernate.loader.hql
não funciona para mim para mostrar os parâmetros
Apenas por conveniência, aqui está o mesmo exemplo de configuração 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>
A saída no seu sql.log (exemplo) fica assim:
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
Mude hibernate.cfg.xml
para:
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
Inclua log4j e entradas abaixo em "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
binding parameter [1] as [VARCHAR] - [1]
.
No caso de inicialização por mola, apenas configure isso:
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 nada mais.
HTH
O Log4JDBC é uma boa solução que imprime o SQL exato que vai para o banco de dados com parâmetros em vez da resposta mais popular aqui, que não faz isso. Uma grande conveniência disso é que você pode copiar o SQL diretamente para o front-end do banco de dados e executar como está.
http://log4jdbc.sourceforge.net/
https://code.google.com/p/log4jdbc-remix/
O último também gera uma representação tabular dos resultados da consulta.
Saída de amostra mostrando o SQL gerado com parâmetros no lugar junto com a tabela do conjunto de resultados da 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 - |---|--------|--------|-----------|----------|---------|-------|
Mais recentemente, agora uso log4jdbc-log4j2 ( https://code.google.com/archive/p/log4jdbc-log4j2/ ) com SLF4j e logback. As dependências do Maven necessárias para minha configuração são as seguintes:
<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>
O driver e os URLs do banco de dados são parecidos com:
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
Meu arquivo de configuração logback.xml é semelhante ao abaixo: isso gera todas as instruções SQL com parâmetros e as tabelas de conjunto de resultados para todas as 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, tive que criar um arquivo chamado log4jdbc.log4j2.properties na raiz do caminho de classe, por exemplo, src / test / resources ou src / main / resources em um projeto Mevn. Este arquivo tem uma linha que é a abaixo:
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
O acima dependerá da sua biblioteca de log. Veja os documentos em https://code.google.com/archive/p/log4jdbc-log4j2 para obter mais informações
Saída de amostra:
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 |
|----------|---|---|----------|--------|---|-----|
|----------|---|---|----------|--------|---|-----|
Você pode adicionar linhas de categoria ao log4j.xml:
<category name="org.hibernate.type">
<priority value="TRACE"/>
</category>
e adicione propriedades de hibernação:
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
adicione as seguintes propriedades e valores à sua configuração log4j ou logback:
org.hibernate.sql=DEBUG
org.hibernate.type.descriptor.sql.BasicBinder=TRACE
org.hibernate.type.descriptor.sql.BasicBinder
categoria não inclui todos os parâmetros, por exemplo, tipos de enumeração. Então, se você quer tudo, você realmente precisa TRACE
para todo o org.hibernate.type
grupo.
Você pode fazer isso usando o proxy da fonte de dados , como descrevi neste post .
Supondo que seu aplicativo espere um dataSource
bean (por exemplo, via @Resource
), é assim que você pode 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"/>
Agora a saída do 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]}
As datasource-proxy
consultas contêm valores de parâmetro e você pode até adicionar interceptores de instruções JDBC customizados para detectar problemas de consulta N + 1 diretamente de seus testes de integração .
<!-- 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>
A solução está correta, mas também registra todas as ligações para os objetos de resultado. Para evitar isso, é possível criar um aplicativo separado e ativar a filtragem, por exemplo:
<!-- 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>
**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
Esta resposta é uma pequena variação para a pergunta. Às vezes, precisamos apenas do sql apenas para fins de depuração em tempo de execução. Nesse caso, há uma maneira mais fácil, usando a depuração nos editores.
Isso é para o hibernate 3. Não tenho certeza de que isso funcione em outras versões.
O driver mysql jdbc já fornece um conveniente para atender a esse requisito, você deve pelo menos ter a versão jar> = mysql-connect-jar-5.1.6.jar
etapa 1: [configure seu jdbc.url para adicionar logger e log personalizado]
jdbc.url=jdbc:mysql://host:port/your_db?logger=com.mysql.jdbc.log.Slf4JLogger&profileSQL=true&profilerEventHandler=com.xxx.CustomLoggingProfilerEventHandler
agora, ele está usando o log slf4j, se o log padrão for log4j, você deve adicionar as dependências slf4j-api, slf4j-log4j12 para usar o log slf4j
etapa 2: [escreva seu log 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();
}
}
Eu gosto disso 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
O registro funciona, mas não exatamente o que você quer ou eu queria há algum tempo, mas o P6Spy funciona perfeitamente ,
aqui está o tutorial simples de implementar também o tutorial MKYONG para P6Spy .
para mim, funcionou como charme.
Obtenha o "p6spy-install.jar"
Extraia o p6spy-install.jar
arquivo, procure p6spy.jar
espy.properties
Adicione p6spy.jar
à sua dependência da biblioteca de projetos
Modifique seu arquivo de configuração do banco de dados. Você precisa substituir o driver JDBC existente pelo driver P6Spy JDBC -com.p6spy.engine.spy.P6SpyDriver
Original é o 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>
Alterado para o driver P6Spy JDBC - 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>
spy.properties
Substitua real driver
por seu driver MySQL JDBC existente
realdriver=com.mysql.jdbc.Driver
#specifies another driver to use
realdriver2=
#specifies a third driver to use
realdriver3=
Alterar o local do arquivo de log Altere o local do arquivo de log na propriedade filefile, todas as instruções SQL farão logon neste arquivo.
janelas
logfile = c:/spy.log
* nix
logfile = /srv/log/spy.log
“spy.properties”
para o caminho de classe do projetoCopie “spy.properties”
para a pasta raiz do projeto, verifique se o seu projeto pode localizar "spy.properties"; caso contrário, ele solicitará a “spy.properties”
exceção do arquivo não encontrado.
<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>
Usando o Hibernate 4 e slf4j / log4j2, tentei adicionar o seguinte na minha configuração 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>
Mas sem sucesso.
Eu descobri através deste thread que a estrutura do jboss-logging usada pelo hibernate precisava ser configurada para fazer o log do slf4j. Adicionei o seguinte argumento aos argumentos da VM do aplicativo:
-Dorg.jboss.logging.provider=slf4j
E funcionou perfeitamente.
Aqui está o que funcionou para mim, defina a propriedade abaixo no log4j.file:
log4j.logger.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Configurações de propriedades do Hibernate:
hibernate.show_sql=true
se você estiver usando o hibernate 3.2.xx, use
log4j.logger.org.hibernate.SQL=trace
ao invés de
log4j.logger.org.hibernate.SQL=debug
Você pode registrar isso:
net.sf.hibernate.hql.QueryTranslator
Exemplo de saída:
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 )
O plugin Log4Jdbc seria o melhor para sua necessidade. Mostra as seguintes
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 o link abaixo para configurar o Log4Jdbc-
https://code.google.com/p/log4jdbc/
Use Wireshark ou algo semelhante:
Nenhuma das respostas acima mencionadas imprimirá sql com parâmetros corretamente ou é uma dor. Consegui isso usando o WireShark , que captura todos os comandos sql / enviados do aplicativo para o Oracle / Mysql etc com as consultas.
Todas as respostas aqui são úteis, mas se você estiver usando um XML de contexto de aplicativo Spring para configurar sua fábrica de sessões, a configuração da variável de nível SQL log4j fará com que você faça parte do caminho até lá, também precisará definir a variável hibernate.show_sql no próprio contexto do aplicativo, para que o Hibernate comece a realmente mostrar os valores.
O ApplicationContext.xml possui:
<property name="hibernateProperties">
<value>
hibernate.jdbc.batch_size=25
... <!-- Other parameter values here -->
hibernate.show_sql=true
</value>
</property>
E seu arquivo log4j precisa
log4j.logger.org.hibernate.SQL=DEBUG
Em Java:
Transforme sua consulta em TypedQuery se for um CriteriaQuery (javax.persistence).
Então:
query.unwrap (org.hibernate.Query.class) .getQueryString ();
O Hibernate mostra a consulta e seus valores de parâmetro em linhas diferentes.
Se você estiver usando application.properties na inicialização por primavera e poderá usar o parâmetro destacado abaixo em application.properties.
org.hibernate.SQL mostrará consultas
org.hibernate.type mostrará todos os valores de parâmetros, que serão mapeados com as consultas de seleção, inserção e atualização. logging.level.org.hibernate.type = TRACE
org.hibernate.type.EnumType mostrará o valor do parâmetro do tipo enum
exemplo ::
2018-06-14 11:06:28,217 TRACE [main] [EnumType.java : 321] Binding [active] to parameter: [1]
sql.BasicBinder mostrará o valor inteiro do parâmetro, varchar, tipo booleano
exemplo ::
A solução mais simples para mim é implementar um stringReplace regular para substituir entradas de parâmetro por valores de parâmetro (tratar todos os parâmetros como string, para simplificar):
String debugedSql = sql;
//then, for each named parameter
debugedSql = debugedSql.replaceAll(":"+key, "'"+value.toString()+"'");
//and finnaly
println(debugedSql);
ou algo semelhante para parâmetros posicionais (?).
Cuide de valores nulos e tipos de valores específicos, como data, se desejar que um sql pronto para execução seja registrado.