Як надрукувати рядок запиту зі значеннями параметрів при використанні Hibernate


393

Чи можливо в сплячому режимі надрукувати згенеровані SQL запити з реальними значеннями замість знаків запитання?

Як би ви запропонували надрукувати запити з реальними значеннями, якщо це неможливо з API Hibernate?


Відповіді:


425

Вам потрібно включити ведення журналу для таких категорій:

  • org.hibernate.SQL   - встановлено для debugреєстрації всіх операторів SQL DML під час їх виконання
  • org.hibernate.type- встановлено для traceреєстрації всіх параметрів JDBC

Отже, конфігурація log4j може виглядати так:

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

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

Перший еквівалентний hibernate.show_sql=trueзастарілому властивості , другий друкує пов'язані параметри серед іншого.

Іншим рішенням (не заснованим на сплячому режимі) було б використання проксі-драйвера JDBC на зразок P6Spy .


11
Це корисно. Але це не показує мені справжні запити SQL.
Ніколя Барбулеско

6
@Nicolas це правда, однак відразу після запиту він розсилає прив’язані параметри.
Xtreme Biker

2
Я використовую grails 2.4.4 та сплячий режим 4. Зміна конфігурації log4j не працювала для мене, але працював p6spy!
Чемп

10
У Hibernate 5 ми можемо використовувати org.hibernate.type.descriptor.sql.BasicBinderреєстратор. Увімкнення реєстрації org.hibernate.typeнадрукованої занадто непотрібної для мене інформації ...
csharpfolk

5
org.hibernate.typeі org.hibernate.loader.hqlне працювати для мене, щоб показати параметри
Dherik

75

Для зручності, ось той самий приклад конфігурації для 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>

Вихід у вашому sql.log (приклад) тоді виглядає так:

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
Це не відповідає на питання ОП.
ShadowGames

33

Змінити hibernate.cfg.xmlна:

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

Включіть записи log4j та нижче в "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

Дякую, дуже добре працював для мене. Ці параметри додадуть під запит sql такий параметр, як binding parameter [1] as [VARCHAR] - [1].
Г. Ciardini

28

У разі використання весняного завантаження просто налаштуйте це:

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

і більше нічого.

HTH


20

Log4JDBC - це приємне рішення, яке друкує точний SQL, що йде в базу даних, з встановленими параметрами, а не найпопулярнішою відповіддю, яка цього не робить. Однією з головних зручностей цього є те, що ви можете скопіювати SQL прямо на передній частині вашої БД та виконати як є.

http://log4jdbc.sourceforge.net/

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

Останній також виводить табличне подання результатів запитів.

Вибірна вибірка, що показує згенерований SQL з парами на місці, разом із таблицею набору результатів із запиту:

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

Оновлення 2016 року

Останнім часом я використовую log4jdbc-log4j2 ( https://code.google.com/archive/p/log4jdbc-log4j2/ ) зі SLF4j та logback. Мая залежність, необхідна для мого налаштування, наведена нижче:

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

URL-адреси драйвера та БД виглядають так:

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 

Мій файл конфігурації logback.xml виглядає наступним чином: він видає всі оператори SQL з параметрами плюс таблиці набору результатів для всіх запитів.

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

Нарешті, мені довелося створити файл з іменем log4jdbc.log4j2.properties в корені classpath, наприклад, src / test / ресурси або src / main / ресурси в проекті Mevn. Цей файл має один рядок, який знаходиться нижче:

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

Вищезазначене буде залежати від вашої бібліотеки реєстрації. Дивіться документацію на https://code.google.com/archive/p/log4jdbc-log4j2 для подальшої інформації

Вибірка зразка:

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
Гей .... Це здається крутим .... просто те, що мені призначив лікар :) ... але чи це також підтримує CLOB / BLOB ?? Також, чи можна відображати лише запит, а не набір результатів. - Дякую :)
dev ray

1
Ви можете надати мені приклад конфігурації, як це зробити?
греп

Насправді останній виводить табличне подання результатів запитів ... тобто потрібен log4jdbc-remix для цієї приємної функції.
meriton

Це рішення найкраще підходило для моєї ситуації, коли мені потрібно було бачити значення рядків, що створюються в сплячому режимі для набору результатів підкачки. Журнал слідів показує лише значення параметрів запиту.
Олівер Ернандес

@Alan Hay також робить цей запит рідними запитами?
Саянтан

9

Ви можете додати рядки категорії до log4j.xml:

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

і додайте сплячі властивості:

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

7

додати наступні властивості та значення до конфігурації log4j або logback:

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

5
У org.hibernate.type.descriptor.sql.BasicBinderкатегорію не входять усі параметри, наприклад, типи enum. Тож якщо ви хочете всього, вам справді потрібно TRACEдля всієї org.hibernate.typeгрупи.
seanf

Для мене це працює в режимі зимування 4,3! Плюс до цього, я не хотів би відслідковувати повний орг.hibernate.type, тому що це занадто великий вихід. У більшості випадків це рішення зробить.
cslotty

Зауважте, що org.hibernate.type.descriptor.sql.BasicExtractor реєструє набори результатів. Тож наявність великого розміру може навіть збити заявку під час входу в консоль у Eclipse, і я вважаю, що це також не ідеально підходить для входу у файл. Ось чому я віддаю перевагу цьому рішенню, воно працює і в сплячому режимі 3. Для тих, хто цікавиться типами перерахунків, будь ласка, спробуйте точний клас, який записує їх, коли org.hibernate.type = TRACE. Потім встановіть org.hibernate.type.xyz.TheClassThatLogsEnumParams = TRACE.
Геза

7

Це можна зробити за допомогою datasource-proxy , як я описав у цій публікації .

Якщо припустити, що ваша програма очікує dataSourceбону (наприклад, через @Resource), ви можете налаштувати 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"/>

Тепер режим сплячого режиму порівняно з 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]}

У datasource-proxyзапитах містять значення параметрів , і ви навіть можете додати власні виписки JDBC - перехоплювачі , так що ви можете зловити N +-питання запитів прямо з ваших тестів інтеграції .


5

увімкніть org.hibernate.typeLogger, щоб побачити, як фактичні параметри прив’язуються до знаків запитання.


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

Рішення правильне, але записує також всі прив’язки для результатів. Щоб запобігти цьому, можливо створити окрему додаток і включити фільтрування, наприклад:

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

Ей однокольорові31 вище рядки потрібно додати у ваш файл конфігурації у сплячому режимі, тоді він обов'язково спрацює. Я завжди публікую те, що практично зробив.
Віджай Бхатт

3

Ця відповідь є невеликою дисперсією для запитання. Іноді нам потрібен sql лише для налагодження під час виконання. У цьому випадку існує більш простий спосіб, за допомогою налагодження в редакторах.

  • Поставте точку перерви на org.hibernate.loader.Loader.loadEntityBatch (або перейдіть по стеку до тих пір);
  • Коли виконання призупинено, подивіться значення змінної this.sql;

Це для сплячого режиму 3. Я не впевнений, що це працює і в інших версіях.


3

mysql jdbc драйвер вже надав зручну для виконання цю вимогу, ви повинні принаймні мати версію jar> = mysql-connect-jar-5.1.6.jar

крок 1: [налаштуйте jdbc.url для додавання реєстратора та користувальницького журналу]

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

тепер він використовує протокол slf4j, якщо ваш журнал за замовчуванням - log4j, ви повинні додати залежності slf4j-api, slf4j-log4j12 для використання журналу slf4j

крок 2: [написати свій користувальницький журнал]

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

Мені це подобається для 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 

Гей - це приємно. Але я думаю, що тут запити друкуються разом із? з подальшими значеннями параметрів. Оскільки у мене є нескінченно багато запитів, мені потрібно щось, що я можу просто скопіювати і вставити в редактор sql, і вони будуть виконані. Чи є спосіб я це зробити, використовуючи такий підхід. Мені не так хочеться ходити по сторонніх бібліотеках. Дякую :)
dev ray

Дякую. Я сподівався не використовувати жодних сторонніх рішень і перезимувати безпосередньо, але, мабуть, у мене немає іншого вибору.
промінь дев

2

Ведення журналу працює, але не зовсім так, як вам цього хотілося, але P6Spy працює чудово ,

ось простий підручник для реалізації, а також підручник MKYONG для P6Spy .

для мене це працювало як шарм.

  1. Завантажте бібліотеку P6Spy

Отримайте "p6spy-install.jar"

  1. Витягніть його

Витягніть p6spy-install.jarфайл, шукайте p6spy.jarіspy.properties

  1. Додайте залежність бібліотеки

Додайте p6spy.jarзалежність від бібліотеки проектів

  1. Змініть файл властивостей P6Spy

Змініть файл конфігурації вашої бази даних. Вам потрібно замінити існуючий драйвер JDBC на драйвер P6Spy JDBC -com.p6spy.engine.spy.P6SpyDriver

Оригінал - драйвер 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>

Змінив його на драйвер 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>
  1. Змініть файл властивостей P6Spy P6Spy -spy.properties

Замініть real driver існуючий драйвер MySQL JDBC

realdriver=com.mysql.jdbc.Driver

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

Змінення місця розташування файлу журналу Змініть розташування файлу журналу у властивості logfile, усі оператори SQL увійдуть у цей файл

Windows

logfile     = c:/spy.log

* нікс

logfile     = /srv/log/spy.log
  1. Скопіюйте “spy.properties”на класний проект

Скопіюйте “spy.properties”у кореневу папку свого проекту, переконайтеся, що ваш проект може знайти "spy.properties", інакше він підкаже, що “spy.properties”файл не знайде виключення.


Це був найпростіший шлях для мене в моєму додатку Spring Boot, де я намагався зафіксувати SQL, сформований з одиничного тесту. Я додав тестову залежність до Gradle (testCompile 'p6spy: p6spy: 3.8.5'), відкоригував application.yml для встановлення spring.datasource.url = jdbc: p6spy: h2: mem: testdb та spring.datasource.driver-class- name = com.p6spy.engine.spy.P6SpyDriver, а потім додано spy.properties з realdriver = org.h2.Driver та logfile, встановлені на мій бажаний шлях. Витягнути повний SQL з отриманого файлу журналу було легко. Єдиною іконою було те, що H2 не сподобався створеному формату часових позначок.
Кен

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>


Як це стосується питання?
hotzst

2

Використовуючи Hibernate 4 та slf4j / log4j2, я спробував додати наступне в конфігурацію 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>

Але без успіху.

Через цей потік я з'ясував, що рамку jboss-журналу, яку використовує сплячка, потрібно налаштувати для входу через slf4j. Я додав наступний аргумент до аргументів VM програми:

-Dorg.jboss.logging.provider=slf4j

І це спрацювало як шарм.


2

Ось що працювало для мене, встановлене нижче властивості в log4j.file:

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

Налаштування властивостей сплячого режиму:

hibernate.show_sql=true

2

для розробки з Wildfly (standalone.xml), додайте ці реєстратори:

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

1

якщо ви використовуєте сплячий режим 3.2.xx

log4j.logger.org.hibernate.SQL=trace

замість

log4j.logger.org.hibernate.SQL=debug 

1

Ви можете ввійти до цього:

net.sf.hibernate.hql.QueryTranslator

Приклад виводу:

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 )

Гей ... я не можу знайти жодного прикладу такого підходу. Чи можете ви надати будь-які довідки / приклади / навчальні посібники. І все-таки це те саме з останніми версіями або в сплячку / log4j, чи він став чимось org.hibernate.QueryTranslator чи щось подібне. Спасибі
промінь

Гей ... Я спробував це, але це, схоже, не працює із збереженням або оновленням. Я думаю, він працює лише для обраних запитів, де перетворюється переклад з hql на sql
dev ray

1

Плагін Log4Jdbc найкраще підходить для ваших потреб. Це показує наступне-

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

Перейдіть посилання нижче для налаштування Log4Jdbc-

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

1

Використовуйте Wireshark або щось подібне:

Жоден з вищезгаданих відповідей не надрукує sql з параметрами належним чином або це біль. Я домігся цього за допомогою WireShark , який фіксує всі sql / команди, що надсилаються з програми в Oracle / Mysql тощо з запитами.


2
Log4JDBC буде. Дивись вище.
Алан Хей

1

Всі відповіді тут корисні, але якщо ви використовуєте контекст програми Spring XML для встановлення фабрики сеансу, встановлення змінної рівня SQL log4j лише отримує частину шляху до вас, ви також повинні встановити змінну hibernate.show_sql. у самому контексті програми, щоб сплячий режим почав фактично показувати значення.

ApplicationContext.xml має:

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

І ваш файл log4j потребує

log4j.logger.org.hibernate.SQL=DEBUG

1

На Java:

Перетворіть свій запит у TypedQuery, якщо це CriteriaQuery (javax.persistence).

Тоді:

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


1
Дякую, він друкує запит, але не параметри, які він використовував, є спосіб надрукувати параметри теж?
Liz Lamperouge

0

Hibernate показує запити та їх параметри в різних рядках.

Якщо ви використовуєте application.properties у весняному завантаженні, і ви можете використовувати нижче виділений параметр у application.properties.

  1. org.hibernate.SQL покаже запити

    logging.level.org.hibernate.SQL = DEBUG

  2. org.hibernate.type покаже всі значення параметрів, які відображатимуть із запитами вибору, вставлення та оновлення. logging.level.org.hibernate.type = TRACE

    • org.hibernate.type.EnumType покаже значення параметра параметра enum

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

      приклад ::

      2018-06-14 11:06:28,217 TRACE [main] [EnumType.java : 321] Binding [active] to parameter: [1]
    • sql.BasicBinder покаже ціле значення, значення varchar, булеве значення параметра типу

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

      приклад ::

      • 2018-06-14 11: 28: 29,750 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] параметр прив’язки [1] як [BOOLEAN] - [true]
      • 2018-06-14 11: 28: 29,751 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] параметр прив’язки [2] як [INTEGER] - [1]
      • 2018-06-14 11: 28: 29,752 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] параметр прив'язки [3] як [VARCHAR] - [public]

1
Навіть це не показує значення для обмеження та зміщення в запитах.
T3rm1

0

Найпростішим рішенням для мене є реалізація звичайного stringReplace для заміни входів параметрів значеннями параметрів (трактуючи всі параметри як рядок, для простоти):

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

або щось подібне для позиційних параметрів (?).
Слідкуйте за нульовими значеннями та типовими типами значень, такими як дата, якщо ви хочете записати готовий sql для запису.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.