Как напечатать строку запроса со значениями параметров при использовании Hibernate


396

Возможно ли в Hibernate печатать сгенерированные запросы SQL с реальными значениями вместо вопросительных знаков?

Как бы вы предложили печатать запросы с реальными значениями, если это невозможно с Hibernate API?


Ответы:


429

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

  • 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, это правда, однако сразу после запроса он отображает связанные параметры.
экстремальный байкер

2
Я использую Grails 2.4.4 и Hibernate 4. Изменение конфигурации log4j у меня не сработало, но сработал p6spy!
Чемпион

11
В Hibernate 5 мы можем использовать org.hibernate.type.descriptor.sql.BasicBinderрегистратор. Включение входа в систему org.hibernate.typeнапечатало слишком много бесполезной информации для меня ...
csharpfolk

5
org.hibernate.typeи org.hibernate.loader.hqlне работать у меня, чтобы показать параметры
Дерик

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].
Дж. Чардини

29

В случае использования весенней загрузки, просто настройте это:

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

и ничего более.

НТН


21

Log4JDBC - хорошее решение, которое печатает точное SQL, идущий в базу данных с параметрами, а не самый популярный ответ, который не делает этого. Одним из основных преимуществ этого является то, что вы можете копировать SQL прямо в интерфейс DB и выполнять как есть.

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. Зависимости Maven, необходимые для моей установки, перечислены ниже:

<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 в корне пути к классам, например, src / test / resources или src / main / resources в проекте 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
Не могли бы вы дать мне пример конфигурации, как это сделать?
grep

На самом деле, последний выводит табличное представление результатов запроса ... т.е. для этой замечательной функции нужен log4jdbc-remix.
меритон

Это решение было лучшим для моей ситуации, когда мне нужно было видеть значения номеров строк, которые Hibernate генерирует для наборов результатов подкачки. В журнале трассировки отображаются только значения параметров запроса.
Оливер Эрнандес

@ Алан Хей тоже ведет этот журнал?
Саянтан

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Категория не включает в себя все параметры, например перечисления типов. Так что если вы хотите всего, вам действительно нужно TRACEдля всей org.hibernate.typeгруппы.
seanf

Для меня это работает в Hibernate 4.3! Кроме того, я бы не отслеживал полный org.hibernate.type, потому что это слишком много. В большинстве случаев это решение подойдет.
cslotty

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

7

Вы можете сделать это, используя datasource-proxy , как я описал в этом посте. .

Предполагая, что ваше приложение ожидает dataSourcebean-компонент (например, через @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"/>

Теперь вывод Hibernate vs datasource-proxy:

INFO  [main]: n.t.d.l.CommonsQueryLoggingListener - Name:, Time:1, Num:1, Query:{[select company0_.id as id1_6_, company0_.name as name2_6_ from Company company0_][]}
INFO  [main]: n.t.d.l.CommonsQueryLoggingListener - Name:, Time:0, Num:1, Query:{[insert into WarehouseProductInfo (id, quantity) values (default, ?)][19]}
INFO  [main]: n.t.d.l.CommonsQueryLoggingListener - Name:, Time:0, Num:1, Query:{[insert into Product (id, code, company_id, importer_id, name, version) values (default, ?, ?, ?, ?, ?)][phoneCode,1,-5,Phone,0]}

В datasource-proxyзапросах содержат значение параметров , и вы даже можете добавить пользовательские выписки JDBC - перехватчики , так что вы можете поймать N +-вопросы запросов прямо из ваших тестов интеграции .



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, указанный выше, должен быть добавлен в ваш файл конфигурации Hibernate, тогда он определенно будет работать. Я всегда публикую то, что я сделал практически.
Виджай Бхатт

3

Этот ответ немного отклоняется от вопроса. Иногда нам нужно только sql только для целей отладки во время выполнения. В этом случае есть более простой способ, используя отладку в редакторах.

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

Это для hibernate 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

Спасибо. Я надеялся, что мне не придется использовать какие-либо сторонние решения и переходить в спящий режим напрямую, но, думаю, у меня нет другого выбора.
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 на драйвер JDBC P6Spy -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=

Измените расположение файла журнала. Измените расположение файла журнала в свойстве файла журнала, все операторы SQL будут входить в этот файл.

Windows

logfile     = c:/spy.log

* Никс

logfile     = /srv/log/spy.log
  1. Скопировать “spy.properties”в classpath проекта

Скопируйте “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 и лог-файлом, установленным по моему предпочтительному пути. Было легко извлечь полный 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-logging, используемый hibernate, необходимо настроить для входа в систему через slf4j. Я добавил следующий аргумент к аргументам виртуальной машины приложения:

-Dorg.jboss.logging.provider=slf4j

И это сработало как шарм.


2

Вот что сработало для меня, установите свойство ниже в файле log4j.file:

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

Настройки свойств Hibernate:

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

если вы используете Hibernate 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 )

Эй ... Я не могу найти никаких примеров такого подхода. Не могли бы вы предоставить какие-либо ссылки / примеры / учебники. И это все еще то же самое с последними версиями или hibernate / log4j, или он стал каким-то org.hibernate.QueryTranslator или что-то еще. Спасибо
dev ray

Эй ... Я пытался это, но это не похоже на сохранение или обновление. Я думаю, что это работает только для запросов на выборку, где перевод с 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

Все ответы здесь полезны, но если вы используете XML-контекст приложения Spring для настройки своей фабрики сеансов, установка переменной уровня SQL log4j только помогает вам в этом, вы также должны установить переменную hibernate.show_sql. в самом контексте приложения, чтобы Hibernate начал показывать значения.

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
Спасибо, он печатает запрос, но не параметры, которые он использовал, есть ли способ напечатать параметры тоже?
Лиз Лампероуг

0

Hibernate показывает запрос и значения его параметров в разных строках.

Если вы используете application.properties при весенней загрузке и можете использовать ниже выделенный параметр в application.properties.

  1. org.hibernate.SQL будет показывать запросы

    logging.level.org.hibernate.SQL = ОТЛАДКА

  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] - [открытый]

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.