So drucken Sie eine Abfragezeichenfolge mit Parameterwerten, wenn Sie den Ruhezustand verwenden


Antworten:


426

Sie müssen die Protokollierung für die folgenden Kategorien aktivieren :

  • org.hibernate.SQL   - festlegen, dass debugalle SQL-DML-Anweisungen bei ihrer Ausführung protokolliert werden
  • org.hibernate.type- auf einstellen, traceum alle JDBC-Parameter zu protokollieren

Eine log4j-Konfiguration könnte also folgendermaßen aussehen:

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

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

Die erste entspricht der hibernate.show_sql=trueLegacy- Eigenschaft , die zweite druckt unter anderem die gebundenen Parameter.

Eine andere Lösung (nicht im Ruhezustand) wäre die Verwendung eines JDBC-Proxy-Treibers wie P6Spy .


11
Das ist nützlich. Dies zeigt mir jedoch nicht die tatsächlichen SQL-Abfragen.
Nicolas Barbulesco

6
@Nicolas das stimmt, aber unmittelbar nach der Abfrage werden die gebundenen Parameter angezeigt.
Xtreme Biker

2
Ich verwende Grails 2.4.4 und Hibernate 4. Das Ändern der log4j-Konfiguration hat bei mir nicht funktioniert, aber p6spy hat funktioniert!
Champ

11
In Hibernate 5 können wir org.hibernate.type.descriptor.sql.BasicBinderLogger verwenden. Durch das Aktivieren der Anmeldung wurden org.hibernate.typezu viele nutzlose Informationen für mich gedruckt ...
csharpfolk

5
org.hibernate.typeund org.hibernate.loader.hqlnicht für mich arbeiten, um die Parameter zu zeigen
Dherik

75

Der Einfachheit halber finden Sie hier das gleiche Konfigurationsbeispiel für 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>

Die Ausgabe in Ihrem sql.log (Beispiel) sieht dann folgendermaßen aus:

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
Dies beantwortet nicht die Frage des OP.
ShadowGames

33

Wechseln hibernate.cfg.xmlzu:

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

Fügen Sie log4j und folgende Einträge in "log4j.properties" ein:

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

Danke, hat bei mir wirklich gut funktioniert. Diese Einstellungen fügen unter der SQL-Abfrage einen Parameter wie hinzu binding parameter [1] as [VARCHAR] - [1].
G. Ciardini

28

Wenn ein Spring Boot verwendet wird, konfigurieren Sie einfach Folgendes:

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

und nichts weiter.

HTH


20

Log4JDBC ist eine nette Lösung, die das genaue SQL druckt , das mit vorhandenen Parametern in die Datenbank gelangt, und nicht die beliebteste Antwort, die dies nicht tut. Ein wesentlicher Vorteil dabei ist, dass Sie SQL direkt in Ihr DB-Frontend kopieren und unverändert ausführen können.

http://log4jdbc.sourceforge.net/

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

Letzteres gibt auch eine tabellarische Darstellung der Abfrageergebnisse aus.

Beispielausgabe, die generiertes SQL mit vorhandenen Parametern zusammen mit der Ergebnismengen-Tabelle aus der Abfrage zeigt:

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

Update 2016

Zuletzt habe ich jetzt log4jdbc-log4j2 ( https://code.google.com/archive/p/log4jdbc-log4j2/ ) mit SLF4j und Logback verwendet. Die für mein Setup erforderlichen Maven-Abhängigkeiten sind wie folgt:

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

Die Treiber- und DB-URLs sehen dann folgendermaßen aus:

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 

Meine Konfigurationsdatei logback.xml sieht wie folgt aus: Hiermit werden alle SQL-Anweisungen mit Parametern sowie die Ergebnismengen-Tabellen für alle Abfragen ausgegeben.

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

Schließlich musste ich eine Datei mit dem Namen log4jdbc.log4j2.properties im Stammverzeichnis des Klassenpfads erstellen, z. B. src / test / resources oder src / main / resources in einem Mevn-Projekt. Diese Datei enthält eine Zeile:

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

Das Obige hängt von Ihrer Protokollierungsbibliothek ab. Weitere Informationen finden Sie in den Dokumenten unter https://code.google.com/archive/p/log4jdbc-log4j2

Beispielausgabe:

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
Hey .... das scheint cool .... genau das, was der Arzt für mich bestellt hat :) ... aber unterstützt es auch CLOB / BLOB ?? Es ist auch möglich, nur die Abfrage und nicht die Ergebnismenge anzuzeigen. - Danke :)
Dev Ray

1
Können Sie mir ein Beispiel für die Konfiguration geben, wie das geht?
Grep

Tatsächlich gibt letzteres eine tabellarische Darstellung der Abfrageergebnisse aus ... dh man benötigt log4jdbc-remix für diese nette Funktion.
Meriton

Diese Lösung war am besten für meine Situation geeignet, in der ich die Zeilennummernwerte anzeigen musste, die der Ruhezustand für Paging-Ergebnismengen generiert. Die Ablaufverfolgungsprotokollierung zeigt nur Abfrageparameterwerte an.
Oliver Hernandez

@Alan Hay protokolliert dies auch native Abfragen?
Sayantan

9

Sie können log4j.xml Kategoriezeilen hinzufügen:

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

und fügen Sie Eigenschaften für den Ruhezustand hinzu:

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

7

Fügen Sie Ihrer log4j- oder logback-Konfiguration folgende Eigenschaften und Werte hinzu:

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

5
Die org.hibernate.type.descriptor.sql.BasicBinderKategorie enthält nicht alle Parameter, z. B. Aufzählungstypen. Wenn Sie also alles wollen, brauchen Sie wirklich TRACEfür die gesamte org.hibernate.typeGruppe.
Seanf

Bei mir funktioniert es in Hibernate 4.3! Außerdem würde ich nicht den vollständigen org.hibernate.type verfolgen, da dies viel zu viel Ausgabe ist. In den meisten Fällen reicht diese Lösung aus.
Cslotty

Beachten Sie, dass org.hibernate.type.descriptor.sql.BasicExtractor die Ergebnismengen protokolliert. Ein großer Eintrag kann sogar die Anwendung beim Anmelden an der Konsole in Eclipse zum Absturz bringen, und ich nehme an, dass dies auch nicht ideal für das Anmelden bei Dateien ist. Deshalb bevorzuge ich diese Lösung, sie funktioniert auch in Hibernate 3. Für diejenigen, die an Aufzählungstypen interessiert sind, probieren Sie bitte die genaue Klasse aus, die sie protokolliert, wenn org.hibernate.type = TRACE. Setzen Sie dann org.hibernate.type.xyz.TheClassThatLogsEnumParams = TRACE.
Géza

7

Sie können dies mit dem Datenquellen-Proxy tun , wie ich in diesem Beitrag beschrieben habe .

Angenommen, Ihre Anwendung erwartet eine dataSourceBean (z. B. via @Resource), können Sie Folgendes konfigurieren 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"/>

Nun die Hibernate-Ausgabe gegen den Datenquellen-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]}

Die datasource-proxyAbfragen enthalten Parameterwerte, und Sie können sogar benutzerdefinierte JDBC-Anweisungsabfangjäger hinzufügen, damit Sie N + 1-Abfrageprobleme direkt aus Ihren Integrationstests heraus erkennen können .


5

Schalten Sie den org.hibernate.typeLogger ein, um zu sehen, wie die tatsächlichen Parameter an die Fragezeichen gebunden werden.


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

Die Lösung ist korrekt, protokolliert jedoch auch alle Bindungen für die Ergebnisobjekte. Um dies zu verhindern, können Sie einen separaten Appender erstellen und die Filterung aktivieren, zum Beispiel:

<!-- 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 obige Zeilen müssen in deine Hibernate-Konfigurationsdatei eingefügt werden, dann wird es definitiv funktionieren. Ich poste immer etwas, was ich praktisch gemacht habe.
Vijay Bhatt

3

Diese Antwort ist eine kleine Abweichung für die Frage. Manchmal benötigen wir die SQL nur für Debug-Zwecke zur Laufzeit. In diesem Fall gibt es eine einfachere Möglichkeit, Debugging für Editoren zu verwenden.

  • Setzen Sie einen Haltepunkt auf org.hibernate.loader.Loader.loadEntityBatch (oder navigieren Sie bis dahin auf dem Stapel).
  • Wenn die Ausführung angehalten wird, überprüfen Sie den Wert der Variablen this.sql.

Dies ist für den Ruhezustand 3. Ich bin nicht sicher, ob dies auf anderen Versionen funktioniert.


3

Der mysql jdbc-Treiber bietet bereits eine praktische Möglichkeit, um diese Anforderung zu erfüllen. Sie müssen mindestens die jar-Version> = mysql-connect-jar-5.1.6.jar haben

Schritt 1: [Konfigurieren Sie Ihre jdbc.url, um Logger und benutzerdefinierte Protokollierung hinzuzufügen]

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

Jetzt wird die slf4j-Protokollierung verwendet. Wenn Ihre Standardprotokollierung log4j ist, müssen Sie die Abhängigkeiten slf4j-api und slf4j-log4j12 hinzufügen, um die slf4j-Protokollierung verwenden zu können

Schritt 2: [Schreiben Sie Ihre benutzerdefinierte Protokollierung]

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

Ich mag das für 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 

Hey - das ist schön. Aber ich denke hier werden die Abfragen mit dem gedruckt? gefolgt von Parameterwerten. Da ich unendlich viele Abfragen habe, brauche ich etwas, das ich einfach in den SQL-Editor kopieren und einfügen kann, und sie werden ausgeführt. Gibt es eine Möglichkeit, dies mit diesem Ansatz zu tun? Ich bin nicht so begeistert von Bibliotheken von Drittanbietern. Danke :)
Dev Ray

Vielen Dank. Ich hatte gehofft, keine Lösungen von Drittanbietern verwenden und direkt in den Ruhezustand wechseln zu müssen, aber ich glaube, ich habe keine andere Wahl.
Dev Ray

2

Die Protokollierung funktioniert, aber nicht genau das, was Sie wollen oder ich wollte vor einiger Zeit, aber P6Spy funktioniert perfekt .

Hier ist das einfache Tutorial, das Sie implementieren können, sowie das MKYONG-Tutorial für P6Spy .

Für mich hat es wie Charme funktioniert.

  1. Laden Sie die P6Spy-Bibliothek herunter

Bekommen das "p6spy-install.jar"

  1. Extrahieren Sie es

Extrahieren Sie die p6spy-install.jarDatei, suchen Sie nach p6spy.jarundspy.properties

  1. Bibliotheksabhängigkeit hinzufügen

Hinzufügen p6spy.jar in Ihre Projektbibliothek Abhängigkeit hinzu

  1. Ändern Sie die P6Spy-Eigenschaftendatei

Ändern Sie Ihre Datenbankkonfigurationsdatei. Sie müssen Ihren vorhandenen JDBC-Treiber durch den P6Spy-JDBC-Treiber ersetzen.com.p6spy.engine.spy.P6SpyDriver

Original ist MySQL JDBC-Treiber - 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>

Geändert in P6Spy JDBC-Treiber - 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. P6Spy-Eigenschaftendatei ändern Ändern Sie die P6Spy-Eigenschaftendatei -spy.properties

Ersetzen Sie den real driverdurch Ihren vorhandenen MySQL JDBC-Treiber

realdriver=com.mysql.jdbc.Driver

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

Ändern des Speicherorts der Protokolldatei Ändern Sie den Speicherort der Protokolldatei in der Eigenschaft logfile. Alle SQL-Anweisungen werden in diese Datei eingeloggt.

Windows

logfile     = c:/spy.log

* nix

logfile     = /srv/log/spy.log
  1. In “spy.properties”Projektklassenpfad kopieren

Kopieren Sie “spy.properties”in Ihren Projektstammordner und stellen Sie sicher, dass Ihr Projekt "spy.properties" finden kann. Andernfalls wird “spy.properties”die Ausnahme " Datei nicht gefunden " angezeigt .


Dies war für mich der einfachste Weg in meiner Spring Boot-Anwendung, in der ich versuchte, aus einem Komponententest generiertes SQL zu protokollieren. Ich habe Gradle eine Testabhängigkeit hinzugefügt (testCompile 'p6spy: p6spy: 3.8.5') und application.yml angepasst, um spring.datasource.url = jdbc: p6spy: h2: mem: testdb und spring.datasource.driver-class- festzulegen name = com.p6spy.engine.spy.P6SpyDriver und fügte dann spy.properties hinzu, wobei realdriver = org.h2.Driver und die Protokolldatei auf meinen bevorzugten Pfad festgelegt waren. Es war einfach, das gesamte SQL aus der resultierenden Protokolldatei zu extrahieren. Das einzige Problem war, dass H2 das generierte Zeitstempelformat nicht mochte.
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>


Wie hängt das mit der Frage zusammen?
Hotzst

2

Mit Hibernate 4 und slf4j / log4j2 habe ich versucht, Folgendes in meine log4j2.xml-Konfiguration aufzunehmen:

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

Aber ohne Erfolg.

Durch diesen Thread habe ich herausgefunden, dass das vom Ruhezustand verwendete jboss-Protokollierungsframework konfiguriert werden muss, um über slf4j zu protokollieren. Ich habe den VM-Argumenten der Anwendung das folgende Argument hinzugefügt:

-Dorg.jboss.logging.provider=slf4j

Und es hat wie ein Zauber funktioniert.


2

Folgendes hat bei mir funktioniert: Setzen Sie die folgende Eigenschaft in der Datei log4j.file:

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

Einstellungen für den Ruhezustand:

hibernate.show_sql=true

2

Fügen Sie für die Entwicklung mit Wildfly (standalone.xml) die folgenden Logger hinzu:

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

1

Wenn Sie den Ruhezustand 3.2.xx verwenden, verwenden Sie

log4j.logger.org.hibernate.SQL=trace

anstatt

log4j.logger.org.hibernate.SQL=debug 

1

Sie können dies protokollieren:

net.sf.hibernate.hql.QueryTranslator

Ausgabebeispiel:

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 )

Hey ... ich kann keine Beispiele für diesen Ansatz finden. Könnten Sie Referenzen / Beispiele / Tutorials bereitstellen? Und ist es immer noch dasselbe mit den neuesten Versionen oder hibernate / log4j oder ist es zu einem org.hibernate.QueryTranslator oder so geworden? Danke
Dev Ray

Hey ... Ich habe es versucht, aber das scheint beim Speichern oder Aktualisieren nicht zu funktionieren. Ich denke, es funktioniert nur für ausgewählte Abfragen, bei denen die Übersetzung von hql nach sql ins Spiel kommt
dev ray

1

Das Log4Jdbc-Plugin ist am besten für Ihre Anforderung geeignet. Es zeigt Folgendes:

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

Siehe untenstehenden Link zum Konfigurieren von Log4Jdbc-

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

1

Verwenden Sie Wireshark oder ähnliches:

Keine der oben genannten Antworten druckt SQL mit den richtigen Parametern oder ist schmerzhaft. Dies wurde durch die Verwendung von WireShark erreicht , das alle SQL / Befehle erfasst, die mit den Abfragen von der Anwendung an Oracle / MySQL usw. gesendet werden.


2
Log4JDBC wird. Siehe oben.
Alan Hay

1

Alle Antworten hier sind hilfreich. Wenn Sie jedoch eine XML-Datei für den Spring-Anwendungskontext verwenden, um Ihre Sitzungsfactory einzurichten, können Sie durch Festlegen der SQL-Variablen log4j nur einen Teil des Weges dorthin zurücklegen. Außerdem müssen Sie die Variable hibernate.show_sql festlegen im App-Kontext selbst, damit Hibernate die Werte tatsächlich anzeigt.

ApplicationContext.xml hat:

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

Und Ihre log4j-Datei benötigt

log4j.logger.org.hibernate.SQL=DEBUG

1

In Java:

Transformieren Sie Ihre Abfrage in TypedQuery, wenn es sich um eine CriteriaQuery handelt (javax.persistence).

Dann:

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


1
Danke, es druckt die Abfrage, aber nicht die Parameter, die es verwendet hat. Gibt es eine Möglichkeit, die Parameter auch zu drucken?
Liz Lamperouge

0

Der Ruhezustand zeigt die Abfrage und ihre Parameterwerte in verschiedenen Zeilen an.

Wenn Sie application.properties im Frühjahrsstart verwenden und den unten hervorgehobenen Parameter in application.properties verwenden können.

  1. org.hibernate.SQL zeigt Abfragen an

    logging.level.org.hibernate.SQL = DEBUG

  2. org.hibernate.type zeigt alle Parameterwerte an, die mit Auswahl-, Einfüge- und Aktualisierungsabfragen verknüpft werden. logging.level.org.hibernate.type = TRACE

    • org.hibernate.type.EnumType zeigt den Parameterwert des Aufzählungstyps an

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

      Beispiel ::

      2018-06-14 11:06:28,217 TRACE [main] [EnumType.java : 321] Binding [active] to parameter: [1]
    • sql.BasicBinder zeigt den Parameterwert Integer, Varchar und Boolescher Typ an

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

      Beispiel ::

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

1
Auch hier werden die Werte für Limit und Offset in Abfragen nicht angezeigt.
T3rm1

0

Die einfachste Lösung für mich ist die Implementierung eines regulären stringReplace, um Parametereingaben durch Parameterwerte zu ersetzen (der Einfachheit halber werden alle Parameter als Zeichenfolge behandelt):

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

oder ähnliches für Positionsparameter (?).
Achten Sie auf Nullwerte und bestimmte Werttypen wie Datum, wenn eine laufbereite SQL protokolliert werden soll.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.