Cách in chuỗi truy vấn với các giá trị tham số khi sử dụng Hibernate


Câu trả lời:


426

Bạn cần kích hoạt đăng nhập cho các danh mục sau:

  • org.hibernate.SQL   - được thiết lập để debugghi nhật ký tất cả các câu lệnh DML của SQL khi chúng được thực thi
  • org.hibernate.type- được thiết lập để traceghi nhật ký tất cả các tham số JDBC

Vì vậy, một cấu hình log4j có thể trông như sau:

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

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

Đầu tiên là tương đương với tàihibernate.show_sql=true sản kế thừa , thứ hai in các tham số ràng buộc trong số những thứ khác.

Một giải pháp khác (không dựa trên chế độ ngủ đông) là sử dụng trình điều khiển proxy JDBC như P6Spy .


11
Điều này rất hữu ích. Nhưng điều này không cho tôi thấy các truy vấn SQL thực sự.
Nicolas Barbulesco

6
@Nicolas điều đó đúng, tuy nhiên ngay sau khi truy vấn, nó sẽ phân tán các tham số bị ràng buộc.
Xtreme Biker

2
Tôi đang sử dụng grails 2.4.4 và hibernate 4. Thay đổi cấu hình log4j không hoạt động với tôi nhưng p6spy đã hoạt động!
Champ

11
Trong Hibernate 5 chúng ta có thể sử dụng org.hibernate.type.descriptor.sql.BasicBinderlogger. Cho phép khai thác gỗ trên org.hibernate.typein quá nhiều thông tin vô ích đối với tôi ...
csharpfolk

5
org.hibernate.typeorg.hibernate.loader.hqlkhông hoạt động để tôi hiển thị các thông số
Dherik

75

Để thuận tiện, đây là ví dụ cấu hình tương tự cho 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>

Đầu ra trong sql.log (ví dụ) của bạn sau đó trông như thế này:

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
Đây không phải là trả lời câu hỏi OP.
ShadowGames

33

Thay đổi hibernate.cfg.xmlthành:

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

Bao gồm các mục log4j và bên dưới trong "log4j.properies":

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

Cảm ơn, đã làm việc cho tôi thực sự tốt. Những cài đặt đó sẽ thêm vào dưới truy vấn sql một tham số như thế nào binding parameter [1] as [VARCHAR] - [1].
G. Ciardini

28

Trong trường hợp khởi động mùa xuân đang được sử dụng, chỉ cần cấu hình này:

ứng dụng.yml

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

ứng dụng

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

và không có gì hơn.

HTH


20

Log4JDBC là một giải pháp tốt đẹp in SQL chính xác đến cơ sở dữ liệu với các tham số tại chỗ thay vì câu trả lời phổ biến nhất ở đây không thực hiện điều này. Một thuận tiện chính của điều này là bạn có thể sao chép SQL thẳng vào giao diện DB của bạn và thực thi như hiện tại.

http://log4jdbc.sourceforge.net/

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

Cái sau cũng xuất ra một biểu diễn dạng bảng của kết quả truy vấn.

Kết quả mẫu hiển thị SQL được tạo với các tham số được đặt cùng với bảng tập kết quả từ truy vấn:

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

Cập nhật 2016

Gần đây nhất tôi đã sử dụng log4jdbc-log4j2 ( https://code.google.com.vn/archive/p/log4jdbc-log4j2/ ) với SLF4j và logback. Maven phụ thuộc cần thiết cho thiết lập của tôi như sau:

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

Các Url Driver và DB sau đó trông giống như:

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 

Tệp cấu hình logback.xml của tôi trông như dưới đây: điều này xuất ra tất cả các câu lệnh SQL với các tham số cộng với các bảng kết quả cho tất cả các truy vấn.

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

Cuối cùng, tôi phải tạo một tệp có tên log4jdbc.log4j2.properies ở thư mục gốc của classpath, ví dụ src / test / resource hoặc src / main / resource trong dự án Mevn. Tập tin này có một dòng dưới đây:

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

Ở trên sẽ phụ thuộc vào thư viện đăng nhập của bạn. Xem các tài liệu tại https://code.google.com.vn/archive/p/log4jdbc-log4j2 để biết thêm thông tin

Đầu ra mẫu:

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
Này .... Điều này có vẻ tuyệt vời .... chỉ là những gì bác sĩ đã yêu cầu cho tôi :) ... nhưng nó cũng hỗ trợ CLOB / BLOB ?? Ngoài ra, có thể chỉ hiển thị truy vấn và không hiển thị kết quả. - Cảm ơn :)
dev ray

1
bạn có thể cho tôi một ví dụ về cấu hình làm thế nào để làm điều đó?
grep

Trên thực tế, cái sau xuất ra một biểu diễn tabluar của kết quả truy vấn ... tức là người ta cần log4jdbc-phối lại cho tính năng hay đó.
meriton

Giải pháp này là tốt nhất cho trường hợp của tôi khi tôi cần xem các giá trị số hàng mà Hibernate tạo cho các tập kết quả phân trang. Ghi nhật ký theo dõi chỉ hiển thị các giá trị tham số truy vấn.
Oliver Hernandez

@Alan Hay này cũng đăng nhập truy vấn gốc?
Sayantan

9

Bạn có thể thêm các dòng danh mục vào log4j.xml:

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

và thêm thuộc tính ngủ đông:

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

7

thêm các thuộc tính và giá trị sau vào cấu hình log4j hoặc logback của bạn:

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

5
Các org.hibernate.type.descriptor.sql.BasicBinderthể loại không bao gồm tất cả các thông số, ví dụ: enum loại. Vì vậy, nếu bạn muốn mọi thứ, bạn thực sự cần TRACEcho toàn bộ org.hibernate.typenhóm.
seanf

Đối với tôi nó hoạt động trong Hibernate 4.3! Thêm vào đó, tôi sẽ không TRACE toàn bộ org.hibernate.type, vì đó là quá nhiều đầu ra. Trong hầu hết các trường hợp, giải pháp này sẽ làm.
cslotty

Lưu ý rằng org.hibernate.type.descriptor.sql.BasicExtractor ghi lại các tập kết quả. Vì vậy, có mục nhập kích thước lớn thậm chí có thể làm hỏng ứng dụng khi đăng nhập vào bàn điều khiển trong Eclipse và tôi cho rằng nó cũng không lý tưởng để đăng nhập vào tệp. Đó là lý do tại sao tôi thích giải pháp này, nó cũng hoạt động trong Hibernate 3. Đối với những người quan tâm đến các loại enum, vui lòng thử lớp chính xác ghi nhật ký chúng khi org.hibernate.type = TRACE. Sau đó, đặt org.hibernate.type.xyz .ClassThatLogsEnumParams = TRACE.
Géza

7

Bạn có thể làm điều đó bằng cách sử dụng proxy nguồn dữ liệu , như tôi đã mô tả trong bài viết này .

Giả sử ứng dụng của bạn mong đợi một dataSourcebean (ví dụ: thông qua @Resource), đây là cách bạn có thể định cấu hình 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"/>

Bây giờ đầu ra Hibernate so với dataource-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]}

Các datasource-proxytruy vấn chứa các giá trị tham số và thậm chí bạn có thể thêm các bộ chặn câu lệnh JDBC tùy chỉnh để bạn có thể bắt được các vấn đề truy vấn N + 1 ngay từ các bài kiểm tra tích hợp của mình .


5

bật org.hibernate.typeLogger để xem các tham số thực tế được liên kết với các dấu hỏi như thế nào.


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

Giải pháp là đúng nhưng cũng ghi nhật ký tất cả các ràng buộc cho các đối tượng kết quả. Để ngăn chặn điều này, nó có khả năng tạo một ứng dụng riêng biệt và cho phép lọc, ví dụ:

<!-- A time/date based rolling appender -->
<appender name="FILE_HIBERNATE" class="org.jboss.logging.appender.DailyRollingFileAppender">
    <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
    <param name="File" value="${jboss.server.log.dir}/hiber.log"/>
    <param name="Append" value="false"/>
    <param name="Threshold" value="TRACE"/>
    <!-- Rollover at midnight each day -->
    <param name="DatePattern" value="'.'yyyy-MM-dd"/>

    <layout class="org.apache.log4j.PatternLayout">
        <!-- The default pattern: Date Priority [Category] Message\n -->
        <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
    </layout>

    <filter class="org.apache.log4j.varia.StringMatchFilter">
        <param name="StringToMatch" value="bind" />
        <param name="AcceptOnMatch" value="true" />
    </filter>
    <filter class="org.apache.log4j.varia.StringMatchFilter">
        <param name="StringToMatch" value="select" />
        <param name="AcceptOnMatch" value="true" />
    </filter>  
    <filter class="org.apache.log4j.varia.DenyAllFilter"/>
</appender> 

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

<logger name="org.hibernate.type">
   <level value="TRACE"/> 
   <appender-ref ref="FILE_HIBERNATE"/>
</logger>

<logger name="org.hibernate.SQL">
   <level value="TRACE"/> 
   <appender-ref ref="FILE_HIBERNATE"/>
</logger>

3
**If you want hibernate to print generated sql queries with real values instead of question marks.**
**add following entry in hibernate.cfg.xml/hibernate.properties:**
show_sql=true
format_sql=true
use_sql_comments=true

**And add following entry in log4j.properties :**
log4j.logger.org.hibernate=INFO, hb
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE
log4j.appender.hb=org.apache.log4j.ConsoleAppender
log4j.appender.hb.layout=org.apache.log4j.PatternLayout

Hey 31 dòng trên phải được thêm vào trong tệp cấu hình ngủ đông của bạn thì nó chắc chắn sẽ hoạt động. Tôi luôn đăng những điều mà tôi đã làm thực tế.
Vijay Bhatt

3

Câu trả lời này là một chút phương sai cho câu hỏi. Đôi khi, chúng ta chỉ cần sql chỉ cho mục đích gỡ lỗi trong thời gian chạy. Trong trường hợp đó, có một cách dễ dàng hơn, sử dụng gỡ lỗi trên các trình soạn thảo.

  • Đặt một điểm dừng trên org.hibernate.loader.Loader.loadEntityBatch (hoặc điều hướng trên ngăn xếp cho đến khi đó);
  • Khi thực thi bị đình chỉ, hãy xem giá trị của biến this.sql;

Đây là dành cho ngủ đông 3. Tôi không chắc rằng nó hoạt động trên các phiên bản khác.


3

Trình điều khiển mysdb jdbc đã cung cấp một cách thuận tiện để đáp ứng yêu cầu này, ít nhất bạn phải có phiên bản jar> = mysql-connect-jar-5.1.6.jar

bước 1: [cấu hình jdbc.url của bạn để thêm logger và ghi nhật ký tùy chỉnh]

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

Bây giờ, nó đang sử dụng ghi nhật ký slf4j, nếu đăng nhập mặc định của bạn là log4j, bạn phải thêm phụ thuộc slf4j-api, slf4j-log4j12 để sử dụng ghi nhật ký slf4j

bước 2: [viết nhật ký tùy chỉnh của bạn]

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

Tôi thích điều này cho 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 

Này - cái này hay đấy. Nhưng tôi nghĩ ở đây các truy vấn được in với? theo sau với các giá trị tham số. Vì tôi có vô số truy vấn, tôi cần một cái gì đó mà tôi có thể chỉ cần sao chép-dán trên trình soạn thảo sql và chúng sẽ được thực thi. Có cách nào tôi có thể làm điều đó bằng cách sử dụng phương pháp này. Tôi không thích đi đến thư viện của bên thứ 3. Cảm ơn :)
dev ray

Cảm ơn. Tôi đã hy vọng không phải sử dụng bất kỳ giải pháp nào của bên thứ 3 và ngủ đông trực tiếp, nhưng tôi đoán tôi không có lựa chọn nào khác.
dev ray

2

Ghi nhật ký hoạt động nhưng không chính xác bạn muốn hoặc tôi muốn một thời gian trước đây, nhưng P6Spy hoạt động hoàn hảo ,

Đây là hướng dẫn đơn giản để thực hiện cũng như hướng dẫn MKYONG cho P6Spy .

Đối với tôi nó làm việc như quyến rũ.

  1. Tải xuống thư viện P6Spy

Nhận phần mềm p6spy-install.jar

  1. Giải nén nó

Giải nén p6spy-install.jartập tin, tìm kiếm p6spy.jarspy.properties

  1. Thêm phụ thuộc thư viện

Thêm p6spy.jarvào phụ thuộc thư viện dự án của bạn

  1. Sửa đổi tệp thuộc tính P6Spy

Sửa đổi tập tin cấu hình cơ sở dữ liệu của bạn. Bạn cần thay thế trình điều khiển JDBC hiện tại của mình bằng trình điều khiển JDBC P6Spy -com.p6spy.engine.spy.P6SpyDriver

Bản gốc là trình điều khiển JDBC của 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>

Đã thay đổi nó thành trình điều khiển 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. Sửa đổi tệp thuộc tính P6Spy Sửa đổi tệp thuộc tính P6Spy -spy.properties

Thay thế real drivertrình điều khiển JDBC MySQL hiện tại của bạn

realdriver=com.mysql.jdbc.Driver

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

Thay đổi vị trí tệp nhật ký Thay đổi vị trí tệp nhật ký trong thuộc tính logfile, tất cả các câu lệnh SQL sẽ đăng nhập vào tệp này.

các cửa sổ

logfile     = c:/spy.log

* nix

logfile     = /srv/log/spy.log
  1. Sao chép “spy.properties”vào classpath dự án

Sao chép “spy.properties”vào thư mục gốc của dự án của bạn, đảm bảo rằng dự án của bạn có thể xác định vị trí của spy spy.properations, nếu không nó sẽ nhắc “spy.properties”tệp không tìm thấy ngoại lệ.


Đây là con đường dễ nhất đối với tôi trong ứng dụng Spring Boot, nơi tôi đang cố gắng đăng nhập SQL được tạo từ một bài kiểm tra đơn vị. Tôi đã thêm một phụ thuộc kiểm tra vào Gradle (testCompile 'p6spy: p6spy: 3.8.5'), điều chỉnh application.yml để đặt spring.datasource.url = jdbc: p6spy: h2: mem: testdb và spring.datasource.driver-class- name = com.p6spy.engine.spy.P6SpyDriver, sau đó thêm spy.properies với realdriver = org.h2.Driver và logfile được đặt thành đường dẫn ưa thích của tôi. Thật dễ dàng để trích xuất SQL hoàn chỉnh từ tệp nhật ký kết quả. Nấc duy nhất là H2 không thích định dạng dấu thời gian được tạo.
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>


Làm thế nào điều này liên quan đến câu hỏi?
hotzst

2

Sử dụng Hibernate 4 và slf4j / log4j2, tôi đã thử thêm phần sau vào cấu hình log4j2.xml của mình:

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

Nhưng không thành công.

Tôi phát hiện ra qua chủ đề này rằng khung đăng nhập jboss được sử dụng bởi hibernate cần phải được cấu hình để đăng nhập thông qua slf4j. Tôi đã thêm đối số sau vào đối số VM của ứng dụng:

-Dorg.jboss.logging.provider=slf4j

Và nó làm việc như một lá bùa.


2

Đây là những gì làm việc cho tôi, đặt bên dưới thuộc tính trong log4j.file:

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

Cài đặt thuộc tính ngủ đông:

hibernate.show_sql=true

2

để phát triển với Wildfly (standalone.xml), hãy thêm các logger đó:

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

1

nếu bạn đang sử dụng hibernate 3.2.xx, hãy sử dụng

log4j.logger.org.hibernate.SQL=trace

thay vì

log4j.logger.org.hibernate.SQL=debug 

1

Bạn có thể đăng nhập này:

net.sf.hibernate.hql.QueryTranslator

Ví dụ đầu ra:

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 )

Này ... tôi không thể tìm thấy bất kỳ ví dụ nào về phương pháp này. Bạn có thể cung cấp bất kỳ tài liệu tham khảo / ví dụ / hướng dẫn. Và nó vẫn giống với các phiên bản mới nhất hoặc hibernate / log4j hoặc nó đã trở thành một số org.hibernate.QueryTranslator hoặc một cái gì đó. Cảm ơn
dev ray

Này ... tôi đã thử cái này, nhưng cái này dường như không hoạt động với lưu hoặc cập nhật. Tôi đoán nó chỉ hoạt động cho các truy vấn được chọn, trong đó dịch từ hql sang sql đi vào hoạt động
dev ray

1

Log4Jdbc plugin sẽ là tốt nhất cho yêu cầu của bạn. Nó cho thấy sau-

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

Tham khảo liên kết dưới đây để cấu hình Log4Jdbc-

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

1

Sử dụng Wireshark hoặc một cái gì đó tương tự:

Không có câu trả lời nào được đề cập ở trên sẽ in sql với các tham số chính xác hoặc là một nỗi đau. Tôi đã đạt được điều này bằng cách sử dụng WireShark , nó nắm bắt tất cả các lệnh sql / được gửi từ ứng dụng tới Oracle / Mysql, v.v. bằng các truy vấn.


2
Log4JDBC sẽ. Xem ở trên.
Alan Hay

1

Tất cả các câu trả lời ở đây đều hữu ích, nhưng nếu bạn đang sử dụng XML bối cảnh ứng dụng Spring để thiết lập nhà máy phiên của mình, việc đặt biến mức SQL log4j chỉ giúp bạn trở thành một phần của cách đó, bạn cũng phải đặt biến hibernate.show_sql trong bối cảnh ứng dụng để Hibernate bắt đầu thực sự hiển thị các giá trị.

ApplicationContext.xml có:

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

Và tập tin log4j của bạn cần

log4j.logger.org.hibernate.SQL=DEBUG

1

Trong Java:

Chuyển đổi truy vấn của bạn trong TypedQuery nếu đó là CriteriaQuery (javax.persistence).

Sau đó:

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


1
Cảm ơn, Nó in truy vấn, nhưng không phải các tham số mà nó sử dụng, có cách nào để in các tham số không?
Liz Lamperouge

0

Hibernate hiển thị truy vấn và các giá trị tham số của chúng trong các dòng khác nhau.

Nếu bạn đang sử dụng application.properations trong spring boot và bạn có thể sử dụng tham số được tô sáng bên dưới trong application.properations.

  1. org.hibernate.SQL sẽ hiển thị các truy vấn

    log.level.org.hibernate.SQL = DEBUG

  2. org.hibernate.type sẽ hiển thị tất cả các giá trị tham số, sẽ ánh xạ với các truy vấn chọn, chèn và cập nhật. log.level.org.hibernate.type = TRACE

    • org.hibernate.type.EnumType sẽ hiển thị giá trị tham số loại enum

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

      thí dụ ::

      2018-06-14 11:06:28,217 TRACE [main] [EnumType.java : 321] Binding [active] to parameter: [1]
    • sql.BasicBinder sẽ hiển thị giá trị tham số kiểu số nguyên, varchar, boolean

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

      thí dụ ::

      • 2018-06-14 11: 28: 29.750 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] tham số ràng buộc [1] dưới dạng [BOOLESE] - [true]
      • 2018-06-14 11: 28: 29,751 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] tham số ràng buộc [2] dưới dạng [INTEGER] - [1]
      • 2018-06-14 11: 28: 29,752 TRACE [http-nio-9891-exec-2] [BasicBinder.java: 65] tham số ràng buộc [3] dưới dạng [VARCHAR] - [công khai]

1
Ngay cả điều này không hiển thị các giá trị giới hạn trong các truy vấn.
T3rm1

0

Giải pháp đơn giản nhất đối với tôi là triển khai chuỗiReplace thông thường để thay thế các đầu vào tham số bằng các giá trị tham số (coi tất cả các tham số là chuỗi, vì đơn giản):

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

hoặc một cái gì đó tương tự cho các tham số vị trí (?).
Chăm sóc các giá trị null và các loại giá trị cụ thể như ngày, nếu bạn muốn một sql sẵn sàng chạy được ghi lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.