Comment imprimer une chaîne de requête avec des valeurs de paramètre lors de L'utilisation D'Hibernate
Est-il possible dans Hibernate d'imprimer des requêtes SQL générées avec des valeurs réelles au lieu de points d'interrogation?
Comment suggéreriez-vous d'imprimer des requêtes avec des valeurs réelles si ce n'est pas possible avec L'API Hibernate?
27 réponses
, Vous devez activer logging pour les catégories suivantes:
-
org.hibernate.SQL
- défini surdebug
pour enregistrer toutes les instructions SQL DML lors de leur exécution -
org.hibernate.type
- défini surtrace
pour enregistrer tous les paramètres JDBC
, Donc une configuration log4j pourrait ressembler à:
# logs the SQL statements
log4j.logger.org.hibernate.SQL=debug
# Logs the JDBC parameters passed to a query
log4j.logger.org.hibernate.type=trace
La première est équivalent à hibernate.show_sql=true
héritage la propriété, le second imprime les paramètres liés entre autres choses.
Une autre solution (non basée sur l'hibernation) serait être d'utiliser un pilote proxy JDBC comme P6Spy .
Juste pour plus de commodité, voici le même exemple de configuration pour 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>
La sortie dans votre sql.journal (exemple) ressemble alors à ceci:
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
Remplacer hibernate.cfg.xml
par:
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
Inclure les entrées log4j et ci-dessous dans "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
Log4JDBC est une bonne solution qui imprime leexact SQL allant à la base de données avec des paramètres en place plutôt que la réponse la plus populaire ici qui ne le fait pas. Une commodité majeure est que vous pouvez copier le SQL directement sur votre front-end DB et l'exécuter tel quel.
Http://log4jdbc.sourceforge.net/
Https://code.google.com/p/log4jdbc-remix/
Ce dernier produit également une représentation tabulaire de la requête résultat.
Exemple de sortie montrant SQL généré avec params en place avec la table de jeu de résultats de la requête:
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 - |---|--------|--------|-----------|----------|---------|-------|
Mise à jour 2016
Plus récemment, j'ai maintenant utilisé log4jdbc-log4j2 ( https://code.google.com/archive/p/log4jdbc-log4j2/) avec SLF4j et logback. Les dépendances Maven requises pour ma configuration sont les suivantes:
<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>
Les URL du pilote et de la base de données ressemblent alors à:
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 #MySQL
Mon logback.fichier de configuration xml ressemble à ce qui suit: cela génère toutes les instructions SQL avec les paramètres ainsi que les tables de resultset pour toutes les requêtes.
<?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>
Enfin, j'ai dû créer un fichier nommé log4jdbc.log4j2.propriétés à la racine du classpath par exemple src/test/resources ou src/main/resources dans un Mevn projet. Ce fichier a une ligne qui est la suivante:
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
Ce qui précède dépendra de votre bibliothèque de journalisation. Voir les documents à https://code.google.com/archive/p/log4jdbc-log4j2 pour plus d'informations
Échantillon Sortie:
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 |
|----------|---|---|----------|--------|---|-----|
|----------|---|---|----------|--------|---|-----|
Vous pouvez ajouter des lignes de catégorie à log4j.xml:
<category name="org.hibernate.type">
<priority value="TRACE"/>
</category>
Et ajouter des propriétés hibernate:
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
Ajoutez les propriétés et valeurs suivantes à votre configuration log4j ou logback:
org.hibernate.sql=DEBUG
org.hibernate.type.descriptor.sql.BasicBinder=TRACE
En cas d'utilisation de Spring boot, config ceci:
Aplication.yml
logging:
level:
org.hibernate.SQL: DEBUG
org.hibernate.type: TRACE
Aplication.propriétés
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
Et rien de plus.
HTH
Activez l'enregistreur org.hibernate.type
pour voir comment les paramètres réels sont liés aux points d'interrogation.
, Vous pouvez le faire en utilisant le source de données-proxy, comme je l'ai décrit dans ce post.
En supposant que votre application attend un bean dataSource
(par exemple via @Resource
), Voici comment vous pouvez configurer 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"/>
Maintenant, la sortie 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]}
Les requêtes datasource-proxy
contiennent des valeurs de paramètres et vous pouvez même ajouter des intercepteurs d'instructions JDBC personnalisés afin que vous puissiez détecter les problèmes de requête N+1 directement à partir de vos tests d'intégration .
**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
<!-- 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>
Cette réponse est une petite variance pour la question. Parfois, nous avons seulement besoin du sql uniquement à des fins de débogage dans l'exécution. Dans ce cas, il existe un moyen plus facile, en utilisant le débogage sur les éditeurs.
- Mettez un point d'arrêt sur org.hiberner.chargeur.Chargeur.loadEntityBatch (ou naviguer sur la pile jusqu'à là);
- Lorsque l'exécution est suspendue, regardez la valeur de la variable this.sql;
Ceci est pour hibernate 3. Je ne suis pas sûr que ce travail sur d'autres versions.
La solution est correcte mais enregistre également toutes les liaisons pour les objets de résultat. Pour éviter cela, il est possible de créer un appender séparé et d'activer le filtrage, par exemple:
<!-- 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>
J'aime ça pour 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
<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>
En utilisant Hibernate 4 et slf4j / log4j2, j'ai essayé d'ajouter ce qui suit dans mon log4j2.configuration 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>
Mais sans succès.
J'ai découvert à travers ce thread {[8] } que le framework JBoss-logging utilisé par hibernate devait être configuré pour se connecter via slf4j. j'ai ajouté l'argument suivant aux arguments VM de l'application:
-Dorg.jboss.logging.provider=slf4j
Et ça a marché comme un charme.
Le pilote Mysql JDBC a déjà fourni une pratique pour répondre à cette exigence, vous devez au moins avoir la version jar > = mysql-connect-jar-5.1.6.jar
Étape 1: [Configurez votre jdbc.url pour ajouter un enregistreur et une journalisation personnalisée]
jdbc.url=jdbc:mysql://host:port/your_db?logger=com.mysql.jdbc.log.Slf4JLogger&profileSQL=true&profilerEventHandler=com.xxx.CustomLoggingProfilerEventHandler
Maintenant, il utilise la journalisation slf4j, si votre journalisation par défaut est log4j, vous devez ajouter des dépendances slf4j-api, slf4j-log4j12 pour utiliser la journalisation slf4j
Étape 2: [écrivez votre journalisation personnalisée]
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();
}
}
Voici ce qui a fonctionné pour moi, défini ci-dessous la propriété dans le fichier log4j:
log4j.logger.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Paramètres des propriétés D'hibernation:
hibernate.show_sql=true
Si vous utilisez hibernate 3.2.XXème utiliser
log4j.logger.org.hibernate.SQL=trace
Au Lieu de
log4j.logger.org.hibernate.SQL=debug
Vous pouvez enregistrer ceci:
net.sf.hibernate.hql.QueryTranslator
Exemple de Sortie:
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 )
Le plugin Log4Jdbc serait le mieux adapté à vos besoins. Il montre ce qui suit -
1. Complete SQL query being hit to the db
2. Parameter values being passed to the query
3. Execution time taken by each query
Reportez - vous au lien ci-dessous pour configurer Log4Jdbc -
https://code.google.com/p/log4jdbc/
Journalisation fonctionne, mais pas exactement ce que vous voulez ou je voulais il y a quelques temps, mais P6Spy fonctionne parfaitement,
Voici le tutoriel simple à implémenter également tutoriel MKYONG pour P6Spy .
Pour moi, cela a fonctionné comme un charme.
- Télécharger la bibliothèque P6Spy
Obtenir le "p6spy-installer.jar "
- extrayez-le
Extrayez le fichier p6spy-install.jar
, recherchez p6spy.jar
et spy.properties
- ajouter une dépendance de bibliothèque
Ajoutez p6spy.jar
dans votre dépendance de bibliothèque de projet
- modifier le fichier de propriétés P6Spy
Modifiez le fichier de configuration de votre base de données. Vous devez remplacer votre pilote JDBC existant par un pilote JDBC P6SPY - com.p6spy.engine.spy.P6SpyDriver
Original est le pilote 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>
L'a changé en pilote 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>
-
Modifier les propriétés P6Spy fichier
Modifier le fichier de propriétés P6Spy -
spy.properties
Remplacez le real driver
par votre pilote JDBC MySQL existant
realdriver=com.mysql.jdbc.Driver
#specifies another driver to use
realdriver2=
#specifies a third driver to use
realdriver3=
Modifier l'emplacement du fichier Journal Modifiez l'emplacement du fichier journal dans la propriété logfile, toutes les instructions SQL se connecteront à ce fichier.
Fenêtres
logfile = c:/spy.log
*nix
logfile = /srv/log/spy.log
-
Copiez
“spy.properties”
dans le chemin de classe du projet
Copiez “spy.properties”
dans le dossier racine de votre projet, assurez-vous que votre projet peut localiser "espion.propriétés", sinon il vous invite “spy.properties”
fichier non trouvé exception.
Utiliser Wireshark ou quelque chose de similaire:
Aucune des réponses mentionnées ci-dessus n'imprimera sql avec des paramètres correctement ou est une douleur. J'ai réalisé cela en utilisant WireShark , qui capture toutes les commandes sql / envoyées de l'application à Oracle / Mysql etc avec les requêtes.
Toutes les réponses ici sont utiles, mais si vous utilisez un XML de contexte D'application Spring pour configurer votre usine de session, la définition de la variable de niveau SQL log4j ne vous permet qu'une partie du chemin, vous devez également définir l'hibernate.variable show_sql dans le contexte de l'application elle-même pour obtenir Hibernate pour commencer à montrer les valeurs.
ApplicationContext.xml a:
<property name="hibernateProperties">
<value>
hibernate.jdbc.batch_size=25
... <!-- Other parameter values here -->
hibernate.show_sql=true
</value>
</property>
Et votre fichier log4j a besoin de
log4j.logger.org.hibernate.SQL=DEBUG
En Java:
Transformez votre requête en TypedQuery si C'est un CriteriaQuery (javax.persistance).
Puis:
Requête.unwrap(org.hiberner.Requête.classe).getQueryString ();
Hibernate affiche la requête et leurs valeurs de paramètres dans différentes lignes.
Si vous utilisez l'application.propriétés dans Spring boot et vous pouvez utiliser le paramètre en surbrillance ci-dessous dans l'application.propriété.
-
Org.hiberner.SQL affichera les requêtes
Journalisation. level. org.hibernate. SQL = débogage
-
Org.hiberner.type affichera toutes les valeurs de paramètres, qui seront mappées avec select, insert et update requête. logging. level. org.hibernate. type = TRACE
-
Org.hiberner.type.EnumType affichera la valeur du paramètre de type enum
Journalisation. level.org.hibernate.type. EnumType = TRACE
Exemple:
2018-06-14 11:06:28,217 TRACE [main] [EnumType.java : 321] Binding [active] to parameter: [1]
-
Sql.BasicBinder affichera integer, varchar, valeur de paramètre de type booléen
Journalisation. level.org.hibernate.type.descriptor.sql. BasicBinder = TRACE
Exemple:
- 2018-06-14 11:28:29,750 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] paramètre de liaison [1] comme [booléen] - [true]
- 2018-06-14 11:28:29,751 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] paramètre de liaison [2] comme [entier] - [1]
- 2018-06-14 11:28:29,752 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] paramètre de liaison [3] comme [VARCHAR] - [public]
-
La solution la plus simple pour moi est d'implémenter un stringReplace régulier pour remplacer les entrées de paramètres par des valeurs de paramètres (en traitant tous les paramètres comme une chaîne, pour simplifier):
String debugedSql = sql;
//then, for each named parameter
debugedSql = debugedSql.replaceAll(":"+key, "'"+value.toString()+"'");
//and finnaly
println(debugedSql);
Ou quelque chose de similaire pour les paramètres de position (?).
Prenez soin des valeurs null et des types de valeurs spécifiques comme date, si vous voulez qu'un sql prêt à l'exécution soit enregistré.