Jak wydrukować ciąg zapytania z wartościami parametrów podczas korzystania z hibernacji


Odpowiedzi:


425

Musisz włączyć rejestrowanie dla następujących kategorii:

  • org.hibernate.SQL   - ustawione na debugrejestrowanie wszystkich instrukcji SQL DML podczas ich wykonywania
  • org.hibernate.type- ustawiony na tracerejestrowanie wszystkich parametrów JDBC

Konfiguracja log4j może wyglądać następująco:

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

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

Pierwszy jest równoważny hibernate.show_sql=truewcześniejszej właściwości , drugi drukuje między innymi powiązane parametry.

Innym rozwiązaniem (nie opartym na hibernacji) byłoby użycie sterownika proxy JDBC, takiego jak P6Spy .


11
To jest przydatne. Ale to nie pokazuje mi prawdziwych zapytań SQL.
Nicolas Barbulesco

6
@Nicolas to prawda, jednak natychmiast po zapytaniu odsyła powiązane parametry.
Xtreme Biker,

2
Używam grails 2.4.4 i hibernacji 4. Zmiana konfiguracji log4j nie działała dla mnie, ale działał p6spy!
Champ

10
W Hibernacji 5 możemy użyć org.hibernate.type.descriptor.sql.BasicBinderloggera. Umożliwianie logowania org.hibernate.typewydrukowało dla mnie zbyt wiele niepotrzebnych informacji ...
csharpfolk,

5
org.hibernate.typei org.hibernate.loader.hqlnie działa dla mnie wyświetlanie parametrów
Dherik,

75

Dla wygody, oto ten sam przykład konfiguracji dla 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>

Dane wyjściowe w pliku sql.log (przykład) wyglądają następująco:

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
To nie odpowiada na pytanie PO.
ShadowGames,

33

Zmień hibernate.cfg.xmlna:

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

Uwzględnij log4j i poniższe wpisy w „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

Dzięki, działało na mnie naprawdę dobrze. Te ustawienia dodają w zapytaniu sql parametr podobny do binding parameter [1] as [VARCHAR] - [1].
G. Ciardini,

28

W przypadku użycia rozruchu wiosennego wystarczy skonfigurować to:

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

i nic więcej.

HTH


20

Log4JDBC to fajne rozwiązanie, które drukuje dokładny SQL idący do bazy danych z wprowadzonymi parametrami, a nie najpopularniejszą odpowiedź tutaj, która tego nie robi. Jedną z głównych zalet tego jest to, że można skopiować kod SQL bezpośrednio do interfejsu użytkownika bazy danych i wykonywać go tak, jak jest.

http://log4jdbc.sourceforge.net/

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

Ta ostatnia wyświetla również tabelaryczną reprezentację wyników zapytania.

Przykładowe dane wyjściowe przedstawiające wygenerowany SQL z parametrami w miejscu wraz z tabelą zestawów wyników z zapytania:

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

Aktualizacja 2016

Ostatnio korzystam z log4jdbc-log4j2 ( https://code.google.com/archive/p/log4jdbc-log4j2/ ) z SLF4j i logback. Zależności Maven wymagane dla mojej konfiguracji są następujące:

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

Adresy URL sterownika i DB wyglądają następująco:

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 

Mój plik konfiguracyjny logback.xml wygląda następująco: wyświetla wszystkie instrukcje SQL z parametrami oraz tabele zestawów wyników dla wszystkich zapytań.

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

Wreszcie musiałem utworzyć plik o nazwie log4jdbc.log4j2.properties w katalogu głównym ścieżki klasy, np. Src / test / resources lub src / main / resources w projekcie Mevn. Ten plik ma jeden wiersz, który jest poniżej:

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

Powyższe będzie zależeć od biblioteki logowania. Zobacz docs na https://code.google.com/archive/p/log4jdbc-log4j2 aby uzyskać więcej informacji

Przykładowe dane wyjściowe:

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
Hej .... To wydaje się fajne .... właśnie to, co lekarz dla mnie zamówił :) ... ale czy obsługuje też CLOB / BLOB? Czy można wyświetlić tylko zapytanie, a nie zestaw wyników. - Dzięki :)
dev ray

1
czy możesz podać przykład konfiguracji, jak to zrobić?
grep,

W rzeczywistości ta ostatnia generuje tabluarową reprezentację wyników zapytań ... tzn. Do poprawienia tej funkcji potrzebny jest remiks log4jdbc.
meriton

To rozwiązanie było najlepsze w mojej sytuacji, gdy potrzebowałem zobaczyć wartości numerów wierszy generowane przez Hibernację dla zestawów wyników stronicowania. Rejestrowanie śledzenia pokazuje tylko wartości parametrów zapytania.
Oliver Hernandez,

@Alan Hay, czy ten dziennik nawiasuje również zapytania?
Sayantan

9

Możesz dodać linie kategorii do log4j.xml:

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

i dodaj właściwości hibernacji:

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

7

dodaj następujące właściwości i wartości do konfiguracji log4j lub logback:

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

5
org.hibernate.type.descriptor.sql.BasicBinderKategoria nie obejmuje wszystkich parametrów, np enum typów. Więc jeśli chcesz wszystkiego, naprawdę potrzebujesz TRACEcałej org.hibernate.typegrupy.
seanf

Dla mnie działa w Hibernacji 4.3! Ponadto nie ŚLEDZIŁEM pełnego typu org.hibernate.typ, ponieważ to zdecydowanie za dużo danych wyjściowych. W większości przypadków to rozwiązanie wystarczy.
cslotty

Zauważ, że org.hibernate.type.descriptor.sql.BasicExtractor rejestruje zestawy wyników. Tak więc wpis o dużym rozmiarze może nawet spowodować awarię aplikacji podczas logowania do konsoli w Eclipse, i przypuszczam, że nie jest również idealny do logowania do pliku. Dlatego wolę to rozwiązanie, działa również w Hibernacji 3. Dla tych, którzy są zainteresowani typami wyliczeń, wypróbuj dokładnie tę klasę, która je rejestruje, gdy org.hibernate.type = TRACE. Następnie ustaw org.hibernate.type.xyz.TheClassThatLogsEnumParams = TRACE.
Géza

7

Możesz to zrobić za pomocą źródła danych proxy , jak opisałem w tym poście .

Zakładając, że Twoja aplikacja oczekuje dataSourcekomponentu bean (np. Via @Resource), możesz skonfigurować 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"/>

Teraz wyjście Hibernacja vs źródło danych 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]}

Te datasource-proxypytania zawierają wartości parametrów i można nawet dodać przechwytujących zwyczaj oświadczenie JDBC tak, że można złapać n + 1 kwestii zapytań bezpośrednio z twoich testów integracyjnych .



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

Rozwiązanie jest poprawne, ale rejestruje również wszystkie powiązania dla obiektów wynikowych. Aby temu zapobiec, możliwe jest utworzenie osobnego programu dołączającego i włączenie filtrowania, na przykład:

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

Hej single31 powyżej linii należy dodać do pliku konfiguracji hibernacji, to na pewno będzie działać. Zawsze publikuję rzeczy, które zrobiłem praktycznie.
Vijay Bhatt

3

Ta odpowiedź jest małą wariancją pytania. Czasami potrzebujemy sql tylko do celów debugowania w czasie wykonywania. W takim przypadku istnieje łatwiejszy sposób, używając debugowania w edytorach.

  • Umieść punkt przerwania na org.hibernate.loader.Loader.loadEntityBatch (lub nawiguj na stosie, aż tam będzie);
  • Kiedy wykonywanie jest zawieszone, spójrz na wartość zmiennej this.sql;

Dotyczy to hibernacji 3. Nie jestem pewien, czy to działa w innych wersjach.


3

Sterownik mysql jdbc już zapewnia wygodę spełnienia tego wymagania, musisz przynajmniej mieć wersję jar> = mysql-connect-jar-5.1.6.jar

krok 1: [skonfiguruj plik jdbc.url, aby dodać rejestrator i rejestrowanie niestandardowe]

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

teraz używa rejestrowania slf4j, jeśli domyślnym logowaniem jest log4j, musisz dodać zależności slf4j-api, slf4j-log4j12, aby korzystać z rejestrowania slf4j

krok 2: [wpisz swoje niestandardowe rejestrowanie]

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

Podoba mi się to dla 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 

Hej - to miłe. Ale myślę, że tutaj zapytania są drukowane za pomocą? następnie z wartościami parametrów. Ponieważ mam nieskończenie wiele zapytań, potrzebuję czegoś, co mogę po prostu skopiować i wkleić w edytorze sql, a zostaną one wykonane. Czy istnieje sposób, w jaki mogę to zrobić przy użyciu tego podejścia? Nie przepadam za bibliotekami stron trzecich. Dzięki :)
dev ray

Dzięki. Miałem nadzieję, że nie będę musiał używać żadnych rozwiązań innych firm i hibernować bezpośrednio, ale chyba nie mam innego wyboru.
dev ray

2

Rejestrowanie działa, ale nie dokładnie tak, jak chciałeś lub jakiś czas temu, ale P6Spy działa idealnie ,

oto prosty samouczek do zaimplementowania również samouczek MKYONG dla P6Spy .

dla mnie działało to jak urok.

  1. Pobierz bibliotekę P6Spy

Pobierz plik „p6spy-install.jar”

  1. Wyodrębnij to

Wyodrębnij p6spy-install.jarplik, wyszukaj p6spy.jarispy.properties

  1. Dodaj zależność od biblioteki

Dodaj p6spy.jardo zależności biblioteki projektów

  1. Zmodyfikuj plik właściwości P6Spy

Zmodyfikuj plik konfiguracyjny bazy danych. Musisz zastąpić istniejący sterownik JDBC sterownikiem P6Spy JDBC -com.p6spy.engine.spy.P6SpyDriver

Oryginał to sterownik JDBC MySQL - 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>

Zmieniono na sterownik 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. Zmodyfikuj plik właściwości P6Spy Zmodyfikuj plik właściwości P6Spy -spy.properties

Zamień na real driveristniejący sterownik JDBC MySQL

realdriver=com.mysql.jdbc.Driver

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

Zmień lokalizację pliku dziennika Zmień lokalizację pliku dziennika we właściwości pliku dziennika, wszystkie instrukcje SQL zostaną zalogowane do tego pliku.

Windows

logfile     = c:/spy.log

*nic

logfile     = /srv/log/spy.log
  1. Skopiuj “spy.properties”do ścieżki klas projektu

Skopiuj “spy.properties”do folderu głównego projektu, upewnij się, że Twój projekt może zlokalizować „spy.properties”, w przeciwnym razie pojawi się monit “spy.properties”o wyjątek nie znaleziony.


To była dla mnie najłatwiejsza droga do przodu w mojej aplikacji Spring Boot, w której próbowałem zalogować SQL wygenerowany z testu jednostkowego. Dodałem zależność testową do Gradle (testCompile 'p6spy: p6spy: 3.8.5'), dostosowałem application.yml, aby ustawić spring.datasource.url = jdbc: p6spy: h2: mem: testdb i spring.datasource.driver-class- name = com.p6spy.engine.spy.P6SpyDriver, a następnie dodał spy.properties z realdriver = org.h2.Driver i plikiem dziennika ustawionym na moją preferowaną ścieżkę. Łatwo było wyodrębnić pełny SQL z wynikowego pliku dziennika. Jedyną czkawką było to, że H2 nie lubił generowanego formatu znaczników czasu.
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>


Jak to się ma do pytania?
najgorętszy

2

Korzystając z Hibernacji 4 i slf4j / log4j2, próbowałem dodać następujące elementy w mojej konfiguracji 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>

Ale bez powodzenia.

Dowiedziałem się za pośrednictwem tego wątku, że struktura logowania jboss używana przez hibernację musi zostać skonfigurowana w celu logowania przez slf4j. Dodałem następujący argument do argumentów VM aplikacji:

-Dorg.jboss.logging.provider=slf4j

I działało jak urok.


2

Oto, co zadziałało dla mnie, ustaw poniżej właściwości w pliku log4j.file:

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

Ustawienia właściwości hibernacji:

hibernate.show_sql=true

2

do programowania w Wildfly (standalone.xml), dodaj te rejestratory:

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

1

jeśli używasz hibernacji 3.2.xx użyj

log4j.logger.org.hibernate.SQL=trace

zamiast

log4j.logger.org.hibernate.SQL=debug 

1

Możesz zalogować to:

net.sf.hibernate.hql.QueryTranslator

Przykład wyjściowy:

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 )

Hej ... Nie mogę znaleźć żadnych przykładów tego podejścia. Czy możesz podać jakieś referencje / przykłady / samouczki. I czy nadal jest tak samo z najnowszymi wersjami lub hibernacją / log4j, czy stał się jakimś org.hibernate.QueryTranslator czy coś takiego. Dzięki
dev ray

Hej ... Próbowałem tego, ale wydaje się, że to nie działa z zapisem lub aktualizacją. Wydaje mi się, że to działa tylko w przypadku wybranych zapytań, w których do gry wchodzi tłumaczenie z hql na sql
dev ray

1

Wtyczka Log4Jdbc najlepiej spełnia Twoje wymagania. Pokazuje następujące-

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

Sprawdź poniższy link, aby skonfigurować Log4Jdbc-

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

1

Użyj Wireshark lub czegoś podobnego:

Żadna z wyżej wymienionych odpowiedzi nie wydrukuje poprawnie sql z parametrami lub nie stanowi problemu. Osiągnąłem to za pomocą WireShark , który przechwytuje wszystkie zapytania sql / wysyłane z aplikacji do Oracle / Mysql itp. Za pomocą zapytań.


2
Log4JDBC będzie. Patrz wyżej.
Alan Hay

1

Wszystkie odpowiedzi tutaj są pomocne, ale jeśli używasz kontekstowego pliku XML aplikacji Spring do skonfigurowania fabryki sesji, ustawienie zmiennej poziomu log4j SQL pozwoli ci tylko częściowo temu zapobiec, musisz również ustawić zmienną hibernacji.show_sql w samym kontekście aplikacji, aby Hibernacja zaczęła faktycznie wyświetlać wartości.

ApplicationContext.xml ma:

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

I twój plik log4j potrzebuje

log4j.logger.org.hibernate.SQL=DEBUG

1

W Javie:

Przekształć zapytanie w TypedQuery, jeśli jest to CriteriaQuery (javax.persistence).

Następnie:

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


1
Dzięki, drukuje zapytanie, ale nie parametry, których użył, czy jest też sposób na wydrukowanie parametrów?
Liz Lamperouge

0

Hibernacja pokazuje zapytanie i ich wartości parametrów w różnych wierszach.

Jeśli używasz application.properties w wiosennym rozruchu i możesz użyć poniżej podświetlonego parametru w application.properties.

  1. org.hibernate.SQL pokaże zapytania

    logowanie.level.org.hibernate.SQL = DEBUG

  2. org.hibernate.type pokaże wszystkie wartości parametrów, które będą mapowane za pomocą zapytań select, insert i update. logowanie.level.org.hibernate.type = TRACE

    • org.hibernate.type.EnumType wyświetli wartość parametru typu wyliczeniowego

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

      przykład ::

      2018-06-14 11:06:28,217 TRACE [main] [EnumType.java : 321] Binding [active] to parameter: [1]
    • sql.BasicBinder wyświetli wartość parametru typu liczba całkowita, varchar, wartość logiczna

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

      przykład ::

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

1
Nawet to nie pokazuje wartości limitu i przesunięcia w zapytaniach.
T3rm1

0

Najprostszym rozwiązaniem dla mnie jest zaimplementowanie zwykłego ciągu stringReplace w celu zastąpienia danych wejściowych parametrów wartościami parametrów (dla uproszczenia traktując wszystkie parametry jako ciąg znaków):

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

lub coś podobnego dla parametrów pozycyjnych (?).
Zadbaj o wartości zerowe i określone typy wartości, takie jak data, jeśli chcesz, aby SQL był gotowy do uruchomienia.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.