5

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

10

Возможность отображения SQL-запросов с реальными значениями в Hibernate

Здравствуйте! Я столкнулся с проблемой: возможно ли в Hibernate выводить сгенерированные SQL-запросы с реальными значениями вместо вопросительных знаков?

Если такой функционал отсутствует в API Hibernate, как бы вы предложили реализовать вывод запросов с реальными значениями? Буду признателен за любые советы или обходные пути!

5 ответ(ов)

1

Если вы используете Spring Boot, просто настройте это:

application.yml

logging:
  level:
    org.hibernate.SQL: DEBUG
    org.hibernate.type: TRACE

или

application.properties

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE

И больше ничего.

Ваши логи будут выглядеть примерно так:

2020-12-07 | DEBUG | o.h.SQL:127 - insert into Employee (id, name, title, id) values (?, ?, ?, ?)
2020-12-07 | TRACE | o.h.t.d.s.BasicBinder:64 - binding parameter [1] as [VARCHAR] - [001]
2020-12-07 | TRACE | o.h.t.d.s.BasicBinder:64 - binding parameter [2] as [VARCHAR] - [John Smith]
2020-12-07 | TRACE | o.h.t.d.s.BasicBinder:52 - binding parameter [3] as [VARCHAR] - [null]
2020-12-07 | TRACE | o.h.t.d.s.BasicBinder:64 - binding parameter [4] as [BIGINT] - [1]
0

Если вы используете Spring Boot 3 и/или Hibernate 6, следующая конфигурация позволит вам отображать значения параметров:

# базовый уровень логирования для всех сообщений
logging.level.org.hibernate=info
# SQL-запросы и параметры
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.orm.jdbc.bind=trace
# Статистика и медленные запросы
logging.level.org.hibernate.stat=debug
logging.level.org.hibernate.SQL_SLOW=info
# Кэш второго уровня
logging.level.org.hibernate.cache=debug

Эта настройка позволит вам более детально видеть, что происходит в процессе выполнения SQL-запросов и работы с кэшем. Убедитесь, что вы правильно настроили уровни логирования, чтобы получить необходимую информацию.

0

Вот пример конфигурации для 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] - [email protected]
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

Эта конфигурация позволяет логировать SQL-запросы и параметры, к которым они привязаны, что может быть полезно для отладки и мониторинга работы приложения.

0

Для активации отображения SQL-запросов и их формата в Hibernate, вам необходимо внести изменения в файл 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-запросы в консоли, а также позволит вам видеть более детальную информацию о типах данных, которые обрабатываются Hibernate. Убедитесь, что log4j подключен к вашему проекту, чтобы эти настройки заработали.

0

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

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

Пример вывода, показывающий сгенерированный 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" />
    
    <!-- РАСКОММЕНТУЙТЕ НИЖЕ, ЧТОБЫ СКРЫТЬ ВЫВОД ТАБЛИЦЫ РЕЗУЛЬТАТОВ -->
    <!--<logger name="jdbc.resultsettable" level="ERROR" /> -->

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

Наконец, я создал файл с именем log4jdbc.log4j2.properties в корне classpath, например, src/test/resources или src/main/resources в проекте Maven. Этот файл имеет одну строку:

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 |
|----------|---|---|----------|--------|---|-----|
|----------|---|---|----------|--------|---|-----|
Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь