XX\tomcat-7.0.42\webapps\ROOT\WEB-INF\classes\log4j.properties
log4j.rootLogger=INFO, CONSOLE

log4j.appender.STDOUT.Threshold=trace
log4j.category.org.hibernate.SQL=trace
log4j.category.org.hibernate.type=trace
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.EnhancedPatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c{1}:%L] %m%n
http://www.liferay.com/zh/community/wiki/-/wiki/Main/How+to+configure+the+logs+in+Liferay

灵活控制 Hibernate 的日志或 SQL 输出,以便于诊断

我们在使用 Hibernate 时一般只会关注是否显示生成的 SQL 语句,不过有些时候还不够。默认时 Hibernate 执行的 SQL 语句是打印在控制台上的,它也可以配置为输出给 Log4J 或是 Log4Back,还能显示出更详细的参数和取值信息。这里简单讲来。

Hibernate 的配置文件 hibernate.cfg.xml 里提供有三个有关显示 SQL 的配置项,如果是与 Spring 联合,也可以配置到 Spring 的配置中。它们的取值是 boolean 值。

1) hibernate.show_sql - 是否显示所生成 SQL 语句,我们最常和它打交道 2) hibernate.format_sql - 是否格式化生成的 SQL 语句,增加可读性,不然全挤在一行 3) hibernate.use_sql_comments - 是否显示注释,用以指出什么操作产生的 SQL 语句,相比上面两条而言,这个配置会稍稍陌生些

来看看加了上面三条配置后产生的效果,执行了 Hibernate 查询后,在控制台上产生如下输出:

Hibernate:     /* load collection cc.unmi.test.model.Post.securities */ select         securities0_.post_id as post1_7_1_,         security1_.shareclassid as sharecla1_16_0_,         security1_.company_id as company2_16_0_,     from         Post_Security_Relationship securities0_     inner join         unmi.securities security1_             on securities0_.shareclassid=security1_.shareclassid     where         securities0_.post_id=?

hibernate.show_sql 控制全局是否显示生成的 SQL 语句,hibernate.format_sql 格式化后的效果如上,不然就是一行,而 hibernate.use_sql_comments 输出的是红色的部分,表明是在加哉 securities 集合时所执行的 SQL 语句。

Hibernate 默认是把 SQL 语句是输出到控制台,而控制台中的内容查阅起来并不方便,例如超过控制台缓存的内容会被清掉,不是谁都能看到控制台,难以与时间关联起来。虽然有些应用服务器会把控制台输出重定向到文件,但总没有 Log4J 或 Slf4J 那样的专业日志工具来得便捷。

因为 Hibernate 在输出 SQL 时使用的 logger 名为 org.hibernate.SQL, 所以想要让 SQL 语句输出到 Log4J 或是 Slf4J 日志中(日志文件或是记在别处,由 Appender 决定的),只要在 log4j.properties(log4j.xml 参考相应配置) 中加上:

log4j.logger.org.hibernate.SQL=DEBUG

记得同时把 Hibernate 配置文件中(或者 Spring 中关于 Hibernate 的配置中) 的 hibernate.show_sql 设置为 false,不然可能在控制台下会有双份输出(Log4J 配置了 ConsoleAppender 时)。

如果就用的是 Log4Back 的话,就在 Log4Back 的配置文件 log4back.xml 中加上:

<logger name="org.hibernate.SQL" level="DEBUG"/>

这时的日志输出格式与控制台下没多少分别,只是跟着 Log4J 或 Slf4J 跑而已,像:

20:13:40.757 [http-8080-1] DEBUG org.hibernate.SQL -     /* load collection cc.unmi.test.model.Post.tags */ select         tags0_.post_id as post1_7_1_,         tags0_.tag_id as tag2_1_,         elementite1_.id as id3_0_,     from         Post_Tag_Relationship tags0_     inner join         unmi.element_item elementite1_             on tags0_.tag_id=elementite1_.id     where         tags0_.post_id=?

只有红色部分不同,应用上了 Log4J 或 Slf4J 的配置了,可以看到执行的时间、线程等相关信息。

我们想知道前面输出的 SQL 语句中的 ? 参数代表的实际值是什么,还需要打开一个日志 org.hibernate.type.descriptor.sql.BasicBinder 的输出级别为 TRACE,这里同时把 org.hibernate.type.descriptor.sql.BasicExtractor 的输出级别也设置为 TRACE,来看看效果:

log4j.properties 中配置为:

log4j.logger.org.hibernate.type.descriptor.sql.BasicBinder=TRACE log4j. loggerorg.hibernate.type.descriptor.sql.BasicExtractor=TRACE

logback.xml 中配置为:

<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/> < logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="TRACE"/>

之后看输出:

20:13:40.710 [http-8080-1] DEBUG org.hibernate.SQL -     /* load collection cc.unmi.test.model.Post.categories */ select         categories0_.post_id as post1_7_1_,         elementite1_.id as id3_0_,     from         Post_Category_Relationship categories0_     inner join         unmi.element_item elementite1_             on categories0_.category_id=elementite1_.id     where         categories0_.post_id=? 20:13:40.710 [http-8080-1] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - 10 20:13:40.710 [http-8080-1] TRACE org.hibernate.type.descriptor.sql.BasicExtractor - found [1002] as column [id3_0_] 20:13:40.710 [http-8080-1] TRACE org.hibernate.type.descriptor.sql.BasicExtractor - found [10] as column [post1_7_1_]

红色部分是 org.hibernate.type.descriptor.sql.BasicBinder=TRACE 控制的,显示了绑定给 SQL 的参数列表。蓝色部分是 org.hibernate.type.descriptor.sql.BasicExtractor=TRACE 控制的,显示了查询后记录的字段值。注意这两个属性是要设置到 TRACE 级别,所以在一般日志的全局 DEBUG 级别之下,它们会表示不受影响。

有时候想要显示查询中命名参数的值,用 :email 而不是 ? 的形式,则还需要引入两个

log4j.logger.org.hibernate.engine.QueryParameters=DEBUG log4j.logger.org.hibernate.engine.query.HQLQueryPlan=DEBUG

效果是这样的:

20:13:40.710 [http-8080-1] org.hibernate.engine.query.HQLQueryPlan - find: from User where email = :email 20:13:40.710 [http-8080-1] org.hibernate.engine.QueryParameters - named parameters: {email=fantasia@sina.com} 20:13:40.726 [http-8080-1] org.hibernate.SQL -     /* named HQL query findUserByEmail */ select         user0_.id as id0_,         user0_.email as email0_,         user0_.enabled as enabled0_,         user0_.encodedPassword as encodedP8_0_     from         User user0_     where         user0_.email=?

对上面综合一下,比较好的配置可以参考:

hibernate.cfg.xml 中配置:

1
2
3
<property name="hibernate.show_sql">false</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>

或者是在 Spring 中关于 Hibernate 的配置属性:

1
2
3
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>

而在日志配置中,如 log4j.properties 中配置:

1
2
3
4
5
log4j.logger.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
log4j.logger.org.hibernate.type.descriptor.sql.BasicExtractor=TRACE
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.engine.QueryParameters=DEBUG
log4j.logger.org.hibernate.engine.query.HQLQueryPlan=DEBUG

倘若用的是 Slf4J 话,就在 logback.xml 中配置:

1
2
3
4
5
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/>
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="TRACE"/>
<logger name="org.hibernate.SQL" level="DEBUG"/>
<logger name="org.hibernate.engine.QueryParameters" level="DEBUG"/>
<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG"/>

如果你会觉得日志太多的话,反正我是会这么觉得,那么可考虑把 org.hibernate.type.descriptor.sql.BasicExtractor 设置为 DEBUG,或不设置该配置项。

注: 本文是在 Hibernate 3.6.0 Final 下做的测试,如果是用的其他版本的 Hibernate,尤其是 Hibernate 2.x 可能配置很不相象了,需斟酌应对。

参考:1. Hibernate Parameter Logging

http://unmi.cc/hibernate-log-sql-log4j-slf4j/

Liferay中SQL打印参数的更多相关文章

  1. C#中SQL语句参数写法

    OracleConnection oc=new OracleConnection("data source=osserver;User Id=****;password=**"); ...

  2. JDBC与Hibernate中SQL语句参数设置的顺序问题

    JDBC中:设置从1开始 例: Connection con = DriverManager.getConnection("jdbc:mysql://localhost/...", ...

  3. PYTHON 中 SQL 带参数

    使用 PYTHON 的字符串填充方式 import mysql.connector sql = 'select \* from school.student where age > {age} ...

  4. sql 解析字符串添加到临时表中 sql存储过程in 参数输入

    sql 解析字符串添加到临时表中  sql存储过程in 参数输入 解决方法 把字符串解析 添加到 临时表中 SELECT * into #临时表   FROM dbo.Func_SplitOneCol ...

  5. sql 中条件in参数问题

    经常遇到条件为in的模糊查询,sql传参可以在service中直接传递参数,不必使用占位符 select * from ud_order where status in ("+status+ ...

  6. SQL Server,Access数据库查询易混点和C#中parameter指定参数长度的优缺点

    在学校的时候就经常做一些网站,所以这次在公司实习,组长第一次给了一个企业的网站还是很快的完成了.中间并没有遇到什么大的问题,但是还是遇到了两个新手非常容易混淆的小问题,所以拿出来跟大家分享一下. 主要 ...

  7. log4j2打印jdbcTemplate的sql以及参数

    log4j2打印jdbcTemplate的sql以及参数 ——IT唐伯虎 摘要: log4j2打印jdbcTemplate的sql以及参数. 在log4j2.xml加上这两个logger即可: < ...

  8. Mybatis中多个参数的问题&&动态SQL&&查询结果与类的对应

    ### 1. 抽象方法中多个参数的问题 在使用MyBatis时,接口中的抽象方法只允许有1个参数,如果有多个参数,例如: Integer updatePassword( Integer id, Str ...

  9. 【spring boot】【mybatis】spring boot中mybatis打印sql语句

    spring boot中mybatis打印sql语句,怎么打印出来?[参考:https://www.cnblogs.com/sxdcgaq8080/p/9100178.html] 在applicati ...

随机推荐

  1. 大白话系列之C#委托与事件讲解(一)

    从序言中,大家应该对委托和事件的重要性有点了解了吧,虽然说我们现在还是能模糊,但是从我的大白话系列中,我会把这些概念说的通俗易懂的.首先,我们还是先说说委托吧,从字面上理解,只要是中国人应该都知道这个 ...

  2. NoSQL之Redis高级实用命令详解--安全和主从复制

    Android IOS JavaScript HTML5 CSS jQuery Python PHP NodeJS Java Spring MySQL MongoDB Redis NOSQL Vim ...

  3. 开发环境安装 Java Mysql MyEclipse Android Adt

    一.安装 JDK 1.官网下载JDK最新版本,下载地址如下: http://www.oracle.com/technetwork/java/javase/downloads/index.html 这里 ...

  4. .net 实现 URL重写,伪静态(方法一)

    一,获得Mircosoft URLRewriter.dll(注意:此dll文件大小约为20KB,网上有8Kb的是不完整的文件,会报错) 二,在项目中该dll文件:添加引用(可以直接拷贝放入Bin文件夹 ...

  5. 导入安卓项目的时候,发生错误:Cause: peer not authenticated

    导入安卓项目时出现Cause: peer not authenticated. 在网上搜了解决方案,都没有凑效.后来干脆插上手机直接debug安装,竟然成功了,成功了,成功了!!!! 然后再次buil ...

  6. WordPress中"无法将上传的文件移动至"错误的解决方法

    #chown -R www:www /wwwroot 今天在网页上传图片到博客,结果提示:“无法将上传的文件移动至 /home/wwwroot/wp-content/uploads/2013/”,郁闷 ...

  7. Nokia 的 Scrum标准

    Nokia 的 Scrum标准:• 迭代要有固定时长(被称为“时间盒——timebox”),不能超过六个星期.• 在每一次迭代的结尾,代码都必须经过 QA 的测试,能够正常工作.• Scrum 团队必 ...

  8. 使用Node.js和Redis实现push服务--转载

    出处:http://blog.csdn.net/unityoxb/article/details/8532028 push服务是一项很有用处的技术,它能改善交互,提升用户体验.要实现这项服务通常有两种 ...

  9. Genymotion出现Unable to load VirtualBox engine问题--100%解决

    首先强调一个事情,作为程序员,一定要养成一个习惯:安装软件时尤其像VirtualBox这类,首先设置其"兼容模式"以及"特权等级" . 环境:win7 64bi ...

  10. android ANR

    下面有两篇关于Android ANR的文章,感觉不错,分享一下! [Android实例] [Sundy系列]网上绝无仅有的Log分析教程及例子!android ANRhttp://blog.csdn. ...