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

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


当前回答

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

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

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

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

其他回答

如果你想让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

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

MySQL JDBC驱动程序已经提供了一个方便的特性来满足这个需求。您必须至少拥有大于或等于5.1.6的JAR版本(例如mysql-connect-jar-5.1.6.jar)。

配置jdbc。添加日志记录器和自定义日志记录器的Url: jdbc.url = jdbc: mysql: / /主持人:港口/ your_db ?记录器= com.mysql.jdbc.log.Slf4JLogger&profileSQL = true&profilerEventHandler = com.xxx.CustomLoggingProfilerEventHandler

它使用slf4j日志记录,如果你的默认日志记录是log4j,你必须添加slf4j-api和slf4j-log4j12作为依赖项来使用slf4j日志记录:

Write your custom logging code: 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 his.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(); } }

这里所有的答案我都有问题。它们实际上都没有为Spring Data JPA查询提供参数,该查询正在作为PK传递枚举。

对于Hibernate 5.3:

    <!-- silence the noise -->
    <Logger name="org.hibernate.search.engine.metadata.impl" additivity="false"/>
    <Logger name="org.hibernate.boot.internal" additivity="false"/>
    <Logger name="org.hibernate.engine.internal" additivity="false"/>
    <Logger name="org.hibernate.engine.jdbc" additivity="false"/>
    <Logger name="org.hibernate.engine.transaction" additivity="false"/>
    <Logger name="org.hibernate.engine.loading.internal" additivity="false"/>
    <Logger name="org.hibernate.engine.spi.CollectionEntry" additivity="false"/>
    <Logger name="org.hibernate.engine.query.spi.HQLQueryPlan" additivity="false"/>
    <Logger name="org.hibernate.engine.query.spi.QueryPlanCache" additivity="false"/>
    <Logger name="org.hibernate.engine.spi.IdentifierValue" additivity="false"/>
    <Logger name="org.hibernate.engine.spi.CascadingActions" additivity="false"/>
    <Logger name="org.hibernate.engine.spi.ActionQueue" additivity="false"/>
    <Logger name="org.jboss.logging"/>
    
    <Logger name="org.hibernate.SQL" level="debug" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>
    <Logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="trace" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>
    <Logger name="org.hibernate.engine" level="trace" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>

hibernate。Format_sql设置为true为漂亮的打印,这是我的输出示例:

17:00:00,664 [TRACE] Named parameters: {1=DE} [main] org.hibernate.engine.spi.QueryParameters.traceParameters(QueryParameters.java:325) 
17:00:00,671 [DEBUG] 
    select
        countrysub0_.code as code1_23_,
        countrysub0_1_.country_subdivision as country_1_61_ 
    from
        country_subdivision countrysub0_ 
    left outer join
        jurisdiction_country_subdivision countrysub0_1_ 
            on countrysub0_.code=countrysub0_1_.jurisdiction 
    where
        countrysub0_.code=? [main] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:103) 

我尝试简单地将org.hibernate.engine.spi.QueryParameters设置为跟踪,但是由于某种原因,命名参数一直被禁用,所以我禁用了所有正在记录日志的其他内容。不过,它似乎没有记录所有参数,所以我仍然需要BasicBinding日志。

将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