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

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


当前回答

你可以记录这个: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 -设置为调试,以便在执行所有SQL DML语句时记录日志 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 

第一种方法相当于冬眠。Show_sql =true遗留属性时,第二个函数将打印绑定的参数。

另一种解决方案(非基于hibernate)是使用像P6Spy这样的JDBC代理驱动程序。

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

日志可以工作,但并不是您想要的,但P6Spy可以完美地工作。

这里有一个简单的教程来实现以及。对我来说,这就像魅力。

下载P6Spy库:获取P6Spy -install.jar 解压:解压p6spy-install.jar文件,查找p6spy.jar和spy.properties 添加库依赖项:将p6spy.jar添加到项目库依赖项中 Modify P6Spy properties file:修改数据库配置文件。您需要用P6Spy JDBC驱动程序替换现有的JDBC驱动程序。

原来是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>  <!-- note the difference -->
  <property name="hibernate.connection.password">password</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/myuser</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>  <!-- note the difference -->
  <property name="hibernate.connection.password">password</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/myuser</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属性文件:spy.properties

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

realdriver=com.mysql.jdbc.Driver

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

在logfile属性中更改日志文件的位置。所有SQL语句都将被记录到这个文件中。

窗口:

logfile=c:/spy.log

UNIX:

logfile=/srv/log/spy.log

复制的间谍。属性到项目类路径:复制间谍。属性添加到项目根文件夹。确保你的项目可以定位间谍。财产,否则就是间谍。属性文件未找到异常将被抛出。

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

使用Wireshark或类似的工具:

上面提到的答案都不会正确地打印带参数的SQL,或者让它与它们一起工作是一件痛苦的事情。我通过使用WireShark实现了这一点,它可以捕获从应用程序发送到Oracle/MySQL等的所有SQL/命令。