在Hibernate中是否有可能用真实值而不是问号打印生成的SQL查询?
如果无法使用Hibernate API,您会建议如何使用实际值打印查询?
在Hibernate中是否有可能用真实值而不是问号打印生成的SQL查询?
如果无法使用Hibernate API,您会建议如何使用实际值打印查询?
当前回答
如果您使用Spring Boot 3和/或Hibernate 6,以下配置将显示参数值:
# basic log level for all messages
logging.level.org.hibernate=info
# SQL statements and parameters
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.orm.jdbc.bind=trace
# Statistics and slow queries
logging.level.org.hibernate.stat=debug
logging.level.org.hibernate.SQL_SLOW=info
# 2nd Level Cache
logging.level.org.hibernate.cache=debug
其他回答
您可以在log4j.xml中添加类别行:
<category name="org.hibernate.type">
<priority value="TRACE"/>
</category>
并添加hibernate属性:
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
如果你想让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
解决方案是正确的,但也记录结果对象的所有绑定。为了防止这种情况,可以创建一个单独的追加器并启用过滤。例如:
<!-- 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>
你可以记录这个: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 )
这个答案对这个问题有点不同。 有时,我们只需要sql在运行时进行调试。 在这种情况下,有一种更简单的方法,在编辑器上使用调试。
在org.hibernate.loader.Loader.loadEntityBatch上放置一个断点(或在堆栈上导航到那里); 当执行暂停时,查看变量this.sql的值
这是针对Hibernate 3的。我不确定这是否适用于其他版本。