10:44:29.400 [main] DEBUG jdbc.sqlonly - org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70)
5. select memberrole0_.member_id as member_i2_12_0_, memberrole0_.id as id1_12_0_, memberrole0_.id
as id1_12_1_, memberrole0_.member_id as member_i2_12_1_, memberrole0_.role_id as role_id3_12_1_,
role1_.id as id1_17_2_, role1_.name as name2_17_2_ from member_roles memberrole0_ left outer
join roles role1_ on memberrole0_.role_id=role1_.id where memberrole0_.member_id=104
10:44:29.402 [main] INFO jdbc.resultsettable -
|----------|---|---|----------|--------|---|-----|
|member_id |id |id |member_id |role_id |id |name |
|----------|---|---|----------|--------|---|-----|
|----------|---|---|----------|--------|---|-----|
**If you want hibernate to print generated sql queries with real values instead of question marks.**
**add following entry in hibernate.cfg.xml/hibernate.properties:**
show_sql=true
format_sql=true
use_sql_comments=true
**And add following entry in 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
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 this.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();
}
}
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 )
2
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
28 回答
对于这个问题,这个答案有点不一致 . 有时,我们只需要在运行时将sql用于调试目的 . 在这种情况下,使用编辑器上的调试有一种更简单的方法 .
在org.hibernate.loader.Loader.loadEntityBatch上放置一个断点(或者在堆栈上导航直到那里);
暂停执行时,查看变量this.sql的值;
这是为了休眠3.我不确定这是否适用于其他版本 .
您需要为以下类别启用logging:
org.hibernate.SQL
- 设置为debug
以记录执行时的所有SQL DML语句org.hibernate.type
- 设置为trace
以记录所有JDBC参数所以log4j配置可能如下所示:
第一个相当于
hibernate.show_sql=true
遗产property,第二个 prints the bound parameters among other things.另一个解决方案(非基于hibernate)将使用像P6Spy这样的JDBC代理驱动程序 .
为方便起见,这里是Logback(SLF4J)的相同配置示例
然后sql.log(示例)中的输出如下所示:
将
hibernate.cfg.xml
更改为:在“log4j.properties”中包含log4j及以下条目:
Log4JDBC是一个很好的解决方案,可以使用参数打印到数据库的确切SQL,而不是这里最常用的答案 . 这样做的一个主要方便是您可以将SQL直接复制到数据库前端并按原样执行 .
http://log4jdbc.sourceforge.net/
https://code.google.com/p/log4jdbc-remix/
后者还输出查询结果的表格表示 .
示例输出显示生成的SQL,其中包含params以及查询中的结果集表:
2016年更新
最近我使用了log4jdbc-log4j2(https://code.google.com/archive/p/log4jdbc-log4j2/)和SLF4j以及logback . 我的设置所需的Maven依赖关系如下:
然后Driver和DB Urls看起来像:
我的logback.xml配置文件如下所示:这将输出所有带有参数的SQL语句以及所有查询的结果集表 .
最后,我必须在类路径的根目录下创建一个名为log4jdbc.log4j2.properties的文件,例如Mevn项目中的src / test / resources或src / main / resources . 这个文件有一行,如下所示:
以上将取决于您的日志库 . 有关详细信息,请参阅https://code.google.com/archive/p/log4jdbc-log4j2上的文档
样本输出:
如果正在使用spring boot,请配置:
aplication.yml
aplication.properties
仅此而已 .
HTH
您可以向log4j.xml添加类别行:
并添加hibernate属性:
将以下属性和值添加到log4j或logback配置中:
您可以使用datasource-proxy来执行此操作,如this post中所述 .
假设您的应用程序需要
dataSource
bean(例如通过@Resource
),这就是配置datasource-proxy
的方法:现在Hibernate输出vs datasource-proxy:
datasource-proxy
查询包含参数值,您甚至可以添加自定义JDBC语句拦截器,以便catch N+1 query issues right from your integration tests .打开
org.hibernate.type
Logger,查看实际参数如何绑定到问号 .解决方案是正确的,但也记录结果对象的所有绑定 . 为了防止这种情况,可以创建一个单独的appender并启用过滤,例如:
我喜欢这个log4j:
使用Hibernate 4和slf4j / log4j2,我尝试在log4j2.xml配置中添加以下内容:
但没有成功 .
我通过this thread发现需要配置hibernate使用的jboss-logging框架以便登录slf4j . 我将以下参数添加到应用程序的VM参数中:
它就像一个魅力 .
mysql jdbc驱动已经提供了方便的满足这个要求,你必须至少有jar版本> = mysql-connect-jar-5.1.6.jar
第1步:[配置您的jdbc.url以添加 Logger 和自定义日志]
现在,它正在使用slf4j日志记录,如果您的默认日志记录是log4j,则必须添加slf4j-api,slf4j-log4j12依赖项以使用slf4j日志记录
第2步:[编写自定义日志记录]
这对我有用,在log4j.file中设置下面的属性:
Hibernate属性设置:
如果你正在使用hibernate 3.2.xx
代替
你可以记录下来:
输出示例:
Log4Jdbc插件最适合您的要求 . 它显示以下 -
请参阅以下链接以配置Log4Jdbc-
记录工作,但不是你想要的或我想要的一段时间,但P6Spy确实工作 perfectly ,
这里是实现的简单教程MKYONG tutorial for P6Spy .
对我而言,它就像魅力一样 .
获取“p6spy-install.jar“
提取
p6spy-install.jar
文件,查找p6spy.jar
和spy.properties
将
p6spy.jar
添加到项目库依赖项中修改数据库配置文件 . 您需要用P6Spy JDBC驱动程序替换现有的JDBC驱动程序 -
com.p6spy.engine.spy.P6SpyDriver
原来是MySQL JDBC驱动程序 -
com.mysql.jdbc.Driver
将其更改为P6Spy JDBC驱动程序 -
com.p6spy.engine.spy.P6SpyDriver
spy.properties
将
real driver
替换为现有的MySQL JDBC驱动程序更改日志文件位置在logfile属性中更改日志文件位置,所有SQL语句都将登录到此文件中 .
视窗
将
“spy.properties”
复制到项目根文件夹,确保您的项目可以找到“spy.properties”,否则它将提示“spy.properties”
文件未找到异常 .使用Wireshark或类似的东西:
上面提到的答案都不会正确打印带有参数的sql,或者是一种痛苦 . 我通过使用WireShark实现了这一点,它使用查询捕获从应用程序发送到Oracle / Mysql等的所有sql /命令 .
这里的所有答案都很有帮助,但是如果您使用Spring应用程序上下文XML来设置会话工厂,那么设置log4j SQL级别变量只会让您在那里获得一部分,您还必须设置hibernate.show_sql变量在app上下文本身让Hibernate开始实际显示值 .
ApplicationContext.xml具有:
你的log4j文件需要
在Java中:
如果它是CriteriaQuery(javax.persistence),则在TypedQuery中转换您的查询 .
然后:
query.unwrap(org.hibernate.Query.class).getQueryString();
Hibernate在不同的行中显示查询及其参数值 .
如果在spring boot中使用application.properties,则可以在application.properties中使用下面突出显示的参数 .
logging.level.org.hibernate.SQL = DEBUG
org.hibernate.type将显示所有参数值,这些参数值将使用select,insert和update查询进行映射 . logging.level.org.hibernate.type = TRACE
org.hibernate.type.EnumType将显示枚举类型参数值
logging.level.org.hibernate.type.EnumType = TRACE
例子::
logging.level.org.hibernate.type.descriptor.sql.BasicBinder = TRACE
例子::
2018-06-14 11:28:29,750 TRACE [http-nio-9891-exec-2] [BasicBinder.java:65]绑定参数[1]为[BOOLEAN] - [true]
2018-06-14 11:28:29,751 TRACE [http-nio-9891-exec-2] [BasicBinder.java:65]绑定参数[2]为[INTEGER] - [1]
2018-06-14 11:28:29,752 TRACE [http-nio-9891-exec-2] [BasicBinder.java:65]绑定参数[3] as [VARCHAR] - [public]
对我来说最简单的解决方案是实现常规stringReplace以使用参数值替换参数输入(为简单起见,将所有参数视为字符串):
或类似的位置参数(?) .
如果要记录运行就绪的sql,请注意空值和特定值类型(如date) .
如果你使用 spring 靴和jpa
告诉hibernate隐藏日志
真的似乎是默认的!!