Hibernate显示真实SQL

437

如果我设置

<property name="show_sql">true</property>
在我的 hibernate.cfg.xml 配置文件中,我可以在控制台上看到SQL语句。

但这并不是真正的 SQL... 我能否看到将直接传递给数据库的SQL代码?

例如:

我看到:

select this_.code from true.employee this_ where this_.code=?

我能看到吗?

select employee.code from employee where employee.code=12

真正的 SQL?


8
Hibernate在内部使用预编译语句,因此它永远不会将SQL语句以值被嵌入的格式呈现。 - Narayan
10
它真的写着 true.employee 吗? - Stephen Denne
5
我发现的唯一可行的解决方案在这里:http://www.mkyong.com/hibernate/how-to-display-hibernate-sql-parameter-values-solution/。 - Christian Achilli
1
与此处所写的相反,我在那里没有找到这个问题的答案:在Hibernate中打印带参数值的查询字符串 - Nicolas Barbulesco
@Narayan - 当然,Hibernate在某个时候会有真正的SQL查询语句。这些真正的查询语句是在发送到数据库之前生成的。 - Nicolas Barbulesco
1
@NicolasBarbulesco 带问号的版本是真正的 SQL。所有 JDBC 驱动程序都可以接受这种格式的查询。在底层,JDBC 驱动程序可能会重新格式化查询以匹配数据库的本地占位符格式(例如,Oracle 和 PostgreSQL 将使用 ? 替换为 :1:2 等),在某些特定情况下,它可能会将绑定占位符替换为转义值(一些 MySQL 驱动程序会这样做)。然而,大多数数据库都能够原生地处理带有占位符的查询。 - James_pic
5个回答

410

我能看到实际的 SQL 吗?

如果您想要查看直接发送到数据库的 SQL(格式与您的示例类似),则必须使用某种 jdbc 驱动程序代理,如 P6Spy(或 log4jdbc)。

或者,您可以启用以下类别的日志记录(在此处使用 log4j.properties 文件):

log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE

第一个与hibernate.show_sql=true等效,第二个会打印绑定的参数等信息。

参考资料


11
我喜欢P6Spy,特别是在运行单元测试时,因为它除了绑定参数值之外,还会给你查询的结果集。 - elduff
1
你能够贴出日志输出的例子吗? - Scarlett
启用 org.hibernate.type 类别对我没有起作用,但是改为启用 org.hibernate.loader.hql 类别则有效。 - Emil Lundberg
你可能需要告诉Hibernate你使用的日志管理器是什么(log4j,slf4j),请参见如何配置 - Vlastimil Ovčáčík
对于 Eclipse Mars,该文件名为 “hibernate-log4j.properties”。 - The Student
显示剩余6条评论

278

log4j.properties

log4j.logger.org.hibernate=INFO, hb
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE
log4j.logger.org.hibernate.hql.ast.AST=info
log4j.logger.org.hibernate.tool.hbm2ddl=warn
log4j.logger.org.hibernate.hql=debug
log4j.logger.org.hibernate.cache=info
log4j.logger.org.hibernate.jdbc=debug

log4j.appender.hb=org.apache.log4j.ConsoleAppender
log4j.appender.hb.layout=org.apache.log4j.PatternLayout
log4j.appender.hb.layout.ConversionPattern=HibernateLog --> %d{HH:mm:ss} %-5p %c - %m%n
log4j.appender.hb.Threshold=TRACE

hibernate.cfg.xml

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

persistence.xml

一些框架使用 persistence.xml

<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>

有没有办法在日志中获取绑定参数的信息? - Rachel
4
@Rachel,除了像“TRACE [BasicBinder] binding parameter [1] as [VARCHAR] - john doe”这样的日志记录之外,你还需要什么? - Arjan
3
不要在 Hibernate 4.3 上工作! - reznic
如果您添加 org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl,则可以从“释放语句”或“关闭准备语句”行(至少在H2中)推断出绑定值。 - TheConstructor
2
@Arjan 将参数单独列出来确实没有什么帮助。 我想要这样的sql输出的部分原因是我可以自己运行语句并查看正在发生的事情。 手动插入参数很笨拙。 遗憾的是,没有更简化打印这些内容的方法。 - Alkanshel
显示剩余3条评论

19

如果您已经可以看到SQL语句被打印出来,那就意味着您在hibernate.cfg.xml文件中拥有以下代码:

<property name="show_sql">true</property>
要同时打印绑定参数,将以下内容添加到您的log4j.properties文件中:
log4j.logger.net.sf.hibernate.type=debug

1
这只适用于 Hibernate 版本小于 3.0,对吗? - Jolly1234
@Brian - 我需要放置 <Loggers></Loggers> 和 appenderRef 吗? - Karen Goh

11

值得注意的是,你看到的代码会按原样发送到数据库,查询语句会分开发送以防止SQL注入。据我所知,“?”号是占位符,由数据库替换为数字参数,而不是由 hibernate 替换。


2

select this_.code from true.employee this_ where this_.code=?将被发送到您的数据库。

this_employee表实例的别名。


16
问题不在于“这个”,而在于“那个”。 - David Anderson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接