在Hibernate中是否有可能用真实值而不是问号打印生成的SQL查询?

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


当前回答

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/

其他回答

解决方案是正确的,但也记录结果对象的所有绑定。为了防止这种情况,可以创建一个单独的追加器并启用过滤。例如:

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

如果你想让Hibernate用真实值而不是问号打印生成的SQL查询,请在Hibernate .cfg.xml/ Hibernate .properties中添加以下条目:

show_sql=true
format_sql=true
use_sql_comments=true

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

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/

使用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日志框架需要配置,以便通过slf4j进行日志记录。我将以下参数添加到应用程序的VM参数中:

-Dorg.jboss.logging.provider=slf4j

而且效果很好。

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

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

或者类似的位置参数(?)。

如果您想要记录运行就绪的SQL,请注意空值和特定的值类型(如date)。