在Hibernate中是否可以用实际值而不是问号来打印生成的SQL查询?

如果Hibernate API无法实现,您如何建议用实际值来打印查询?

评论

另请参见stackoverflow.com/questions/2536829/hibernate-show-real-sql

#1 楼

您需要为以下类别启用日志记录:



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。

评论


这很有用。但这并没有显示真正的SQL查询。

–尼古拉斯·巴布列斯科(Nicolas Barbulesco)
2013年9月3日在8:26



@Nicolas是正确的,但是查询后立即显示绑定的参数。

– Xtreme Biker
2013年9月19日下午6:47

我正在使用grails 2.4.4和hibernate4。更改log4j配置对我不起作用,但p6spy起作用了!

–冠军
15年1月13日在7:03

在Hibernate 5中,我们可以使用org.hibernate.type.descriptor.sql.BasicBinder记录器。启用org.hibernate.type登录对我来说打印了太多无用的信息...

–csharpfolk
16年8月8日在18:15



org.hibernate.type和org.hibernate.loader.hql不适合我显示参数

– Dherik
16-10-6在15:54

#2 楼

为了方便起见,这是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


评论


这没有回答OP的问题。

–ShadowGames
19-10-15在8:52

#3 楼

如果使用的是Spring Boot,只需配置以下内容:
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

,仅此而已。
您的日志将如下所示:
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]

HTH

#4 楼

hibernate.cfg.xml更改为:

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


在“ log4j.properties”中包括log4j及以下条目:

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查询下添加一个参数,例如绑定参数[1]作为[VARCHAR]-[1]。

– G. Ciardini
19年5月7日在8:34

#5 楼

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



Update 2016

最近,我最近一直在使用log4jdbc-使用SLF4j和logback的log4j2(https://code.google.com/archive/p/log4jdbc-log4j2/)。我的设置所需的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>


然后,驱动程序和数据库Urls看起来像:

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的文件,例如Mevn项目中的src / test / resources或src / main / resources。该文件包含以下内容:

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


评论


嘿....这看起来很酷....正是医生为我订购的:) ...但是它也支持CLOB / BLOB吗?此外,是否可以仅显示查询而不显示结果集。 - 谢谢 :)

– dev ray
2014年8月27日10:29



您能给我一个配置示例吗?

– grep
2014年12月8日15:33

实际上,后者输出的是查询结果的表格格式表示,即该功能需要log4jdbc-remix。

– Meriton
16年6月2日在16:56



此解决方案最适合我需要查看Hibernate为分页结果集生成的行号值的情况。跟踪日志记录仅显示查询参数值。

–奥利弗·埃尔南德斯(Oliver Hernandez)
17年1月9日在18:54

@Alan Hay也会记录本机查询吗?

– Sayantan
19年7月30日在1:15

#6 楼

您可以将类别行添加到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


评论


org.hibernate.type.descriptor.sql.BasicBinder类别不包括所有参数,例如枚举类型。因此,如果您需要所有内容,那么对于整个org.hibernate.type组,您确实需要TRACE。

–seanf
2014年4月23日下午5:32

对我来说,它可以在Hibernate 4.3中使用!另外,我不会跟踪完整的org.hibernate.type,因为那样会产生太多输出。在大多数情况下,此解决方案可以。

–cslotty
16 Mar 16 '16 at 12:43

请注意,org.hibernate.type.descriptor.sql.BasicExtractor记录结果集。因此,在Eclipse中登录控制台时,具有大尺寸条目甚至会导致应用程序崩溃,我想它也不适合登录文件。这就是为什么我更喜欢这种解决方案的原因,它也可以在Hibernate 3中使用。对于那些对枚举类型感兴趣的人,请尝试在org.hibernate.type = TRACE时记录它们的确切类。然后设置org.hibernate.type.xyz.TheClassThatLogsEnumParams = TRACE。

–Géza
18/12/21在9:29

#8 楼

您可以使用数据源代理来完成此操作,如我在本文中所述。

假设您的应用程序需要一个dataSource bean(例如,通过@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输出与数据源代理:

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 + 1个查询问题。

#9 楼

打开org.hibernate.type记录器以查看实际参数如何绑定到问号。

#10 楼






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




#11 楼

该解决方案是正确的,但还记录了结果对象的所有绑定。
为避免这种情况,可以创建一个单独的附加程序并启用过滤,例如:

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


#12 楼

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


评论


嘿,上面的单行代码必须添加到您的休眠配置文件中,然后它肯定可以工作。我总是张贴我已经完成的事情。

– Vijay Bhatt
15年7月2日在10:04

#13 楼

对于这个问题,这个答案略有不同。
有时,我们仅需要sql即可在运行时进行调试。
在这种情况下,有一种更简单的方法,可以在编辑器上使用debug。
/>

在org.hibernate.loader.Loader.loadEntityBatch上放置一个断点(或在堆栈上导航直到那里);
当执行被挂起时,查看变量this.sql的值;

这是用于休眠3的。我不确定在其他版本上是否可以使用此功能。

#14 楼

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();
    }

}


#15 楼

要使用Wildfly(standalone.xml)进行开发,请添加以下记录器:

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


#16 楼

我喜欢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
2014年8月27日10:33



谢谢。我希望不必使用任何第三方解决方案并直接休眠,但是我想我别无选择。

– dev ray
2014年9月12日上午8:25

#17 楼

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/


#18 楼

日志记录可以工作,但不是您想要的或我前一段时间想要的,但是P6Spy确实可以正常工作,

这是实现P6Spy的简单教程以及MKYONG教程。

对我而言,它就像魅力一样。



下载P6Spy库

获取“ p6spy-install.jar”


提取它

提取p6spy-install.jar文件,查找p6spy.jarspy.properties


添加库依赖项

添加p6spy.jar进入项目库依赖项


修改P6Spy属性文件

修改数据库配置文件。您需要用P6Spy JDBC驱动程序替换现有的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>




修改P6Spy属性文件
修改P6Spy属性文件– spy.properties

用现有的MySQL JDBC驱动程序替换real driver

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


* nix

logfile     = /srv/log/spy.log



“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-名称= com.p6spy.engine.spy.P6SpyDriver,然后添加带有realdriver = org.h2.Driver和日志文件设置为我首选路径的spy.properties。从结果日志文件中提取完整的SQL很容易。唯一的问题是H2不喜欢生成的时间戳格式。

– Ken Pronovici
19年9月8日15:15

#19 楼






<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
16 Mar 25 '16 at 12:01

#20 楼

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


,但没有成功。

我通过该线程发现,需要配置hibernate使用的jboss-logging框架才能登录slf4j。我在应用程序的VM参数中添加了以下参数:

-Dorg.jboss.logging.provider=slf4j


,它的工作就像一个魅力。

#21 楼

这是对我有用的方法,在log4j.file中设置以下属性:

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


休眠属性设置:

hibernate.show_sql=true


#22 楼

如果您正在使用休眠3.2.xx
请使用

log4j.logger.org.hibernate.SQL=trace


而不是

log4j.logger.org.hibernate.SQL=debug 


#23 楼

您可以记录以下内容:

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
2014年8月27日上午11:23

嘿...我尝试过此操作,但这似乎不适用于保存或更新。我猜这仅适用于选择查询,其中从hql到sql的转换起作用

– dev ray
2014年8月28日上午11:01

#24 楼

使用Wireshark或类似的东西:

以上提到的答案中的任何一个都不会正确地打印带有参数的sql或很痛苦。我通过使用WireShark实现了这一点,WireShark捕获了所有带有查询的从应用程序发送到Oracle / Mysql等的sql /命令。

评论


Log4JDBC将。往上看。

–艾伦·海伊(Alan Hay)
13-10-10在15:18

#25 楼

这里的所有答案都很有帮助,但是如果您使用Spring应用程序上下文XML来设置会话工厂,则设置log4j SQL级别变量只会使您陷入困境,还必须设置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


#26 楼

在Java中:如果是CriteriaQuery(javax.persistence),请在TypedQuery中转换查询。

然后:

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

评论


谢谢,它打印查询,但不打印查询所使用的参数,也可以打印参数吗?

– Liz Lamperouge
19年4月4日在10:55

对不起,我认为不可能像这样映射它们。我会记录它们并作为解决方法手动完成工作;)

–FrédéricNell
11月27日14:00

#27 楼

Hibernate在不同的行中显示查询及其参数值。

如果您在Spring Boot中使用application.properties,则可以在application.properties中使用以下突出显示的参数。



org.hibernate.SQL将显示查询

logging.level.org.hibernate.SQL = DEBUG


org.hibernate。 type将显示所有参数值,这些参数值将与select,insert和update查询映射。
logging.level.org.hibernate.type = TRACE



org .hibernate.type.EnumType将显示枚举类型参数值

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跟踪[http-nio-9891-exec-2] [BasicBinder.java:65]绑定参数[2]为[INTEGER]-[1]
2018-06-14 11:28:29,752跟踪[http-nio-9891-exec-2] [BasicBinder.java:65]绑定参数[3]为[VARCHAR]-[public]






评论


即使这样也不显示查询中的限制和偏移量值。

– T3rm1
19年1月4日在13:10

#28 楼

对我来说,最简单的解决方案是实现常规的stringReplace,以用参数值替换参数输入(为简单起见,将所有参数都视为字符串):

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


参数(?)。
如果要记录运行就绪的sql,请注意空值和特定值类型(如date)。

#29 楼

hibernate-types提供了一种实用的方法来记录jpql和条件查询。
更多详细信息可以在autors的博客文章中找到。这是使用jpql的示例:
Query jpql = entityManager.createQuery("""
    select
       YEAR(p.createdOn) as year,
       count(p) as postCount
    from
       Post p
    group by
       YEAR(p.createdOn)
    """, Tuple.class
);
String sql = SQLExtractor.from(jpql);

sql变量具有以下值:
SELECT
    extract(YEAR FROM sqlextract0_.created_on) AS col_0_0_,
    count(sqlextract0_.id) AS col_1_0_
FROM
    post p
GROUP BY
    extract(YEAR FROM p.created_on)

可以将其直接复制粘贴到db控制台中。

#30 楼

它适用于我
logging.level.org.hibernate.SQL = DEBUG