在使用hibernate的getHibernateTemplate()时怎么让控制台输出封装好的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 中配置:
<property name="hibernate.show_sql">false</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
或者是在 Spring 中关于 Hibernate 的配置属性:
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
而在日志配置中,如 log4j.properties 中配置:
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 中配置:
<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的getHibernateTemplate()时怎么让控制台输出封装好的SQL? 怎么用日志打印出来?的更多相关文章
- pytest文档41-参数化 ids 用例描述为中文时控制台输出unicode编码问题(pytest_collection_modifyitems)
前言 使用 pytest.mark.parametrize 参数化的时候,加 ids 参数用例描述有中文时,在控制台输出会显示unicode编码,中文不能正常显示. 使用 pytest_collect ...
- J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用
J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用 spring 中获得由spring所配置的hibernate的操作对象,然后利用此对象进行,保存,修 ...
- 配置Hibernate二级缓存时,不能初始化RegionFactory的解决办法
配置Hibernate 二级缓存时,出现以下bug提示: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder&quo ...
- Spring Boot + JPA(hibernate 5) 开发时,数据库表名大小写问题
(转载)Spring Boot + JPA(hibernate 5) 开发时,数据库表名大小写问题 这几天在用spring boot开发项目, 在开发的过程中遇到一个问题hibernate在执 ...
- 在配置hibernate.cfg.xml时需指定使用数据库的方言:
在配置hibernate.cfg.xml时需指定使用数据库的方言: 例: <property name="dialect">org.hibernate.dialect. ...
- hibernate执行createSQLQuery时字段重名的问题
hibernate执行createSQLQuery时字段重名的问题 不同表关联 ,表字段重名 =>之前若 as 别名 会自动区分 但有一次签移到新服务器 mysql 5.5上: 若字段重名:重 ...
- 关于Hibernate在反向工程时无法选择Spring DAO Type的解决方法【更新版】
目录(?)[+] IT程序员开发必备-各类资源下载清单,史上最全IT资源,个人收藏总结! 之前有一篇文章中(Hibernate反向工程步骤及DAO Type无法选择Spring DAO解决方法)提到, ...
- hibernate部分源码解析and解决工作上关于hibernate的一个问题例子(包含oracle中新建表为何列名全转为大写且通过hibernate取数时如何不用再次遍历将列名(key)值转为小写)
最近在研究系统启动时将数据加载到内存非常耗时,想着是否有办法优化!经过日志打印测试发现查询时间(查询时间:将数据库数据查询到系统中并转为List<Map>或List<*.Class& ...
- SpringMVC 中,当前台传入多个参数时,可将参数封装成一个bean类
在实际业务场景中,当前台通过 url 向后台传送多个参数时,可以将参数封装成一个bean类,在bean类中对各个参数进行非空,默认值等的设置. 前台 url ,想后台传送两个参数,userName 和 ...
随机推荐
- 浅谈script标签中的async和defer
script标签用于加载脚本与执行脚本,在前端开发中可以说是非常重要的标签了.直接使用script脚本的话,html会按照顺序来加载并执行脚本,在脚本加载&执行的过程中,会阻塞后续的DOM渲染 ...
- 前端工程化grunt
1.grunt是什么? grunt是基于nodejs的前端构建工具.grunt用于解决前端开发的工程问题. 2.安装nodejs Grunt和所有grunt插件都是基于nodejs来运行的. 安装了n ...
- 起名字好难啊!(初识Django)
这次我们将实现一个简单的登录注册功能,并吧相应的数据写入数据库: 做这件事之前我已经在数据库中新建了两张表(当然一张表也可以用,先注册后登录嘛···) 两张结构很简单的数据表:↓ 接下来就该干正 ...
- 解决Ubuntu中phpmyadmin对数据上传上限2M
本文部分参考自:http://www.myhack58.com/Article/sort099/sort0102/2011/29396.htm 原文有少量错误或者过时的(相对于ubuntu15来说)内 ...
- 快速排序算法分析--C++版
快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试喜欢考这个. 快速排序是C.R.A.Hoar ...
- 【转】地址空间、内核空间、IO地址空间
http://blog.csdn.net/wuxinke_blog/article/details/8769131 有这么一系列的问题,是否在困扰着你:用户程序编译连接形成的地址空间在什么范围内?内核 ...
- Java Condition
在Condition中,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll(),传统线程的通信方式,Condition都可以实现, ...
- Spark 基本概念
Application:用户编写的 Spark 应用程序,包含驱动程序(Driver),和分布在集群中多个节点上运行的 Executor 代码,在执行过程中由一个或多个作业组成 Driver(驱动程序 ...
- Oracle:sqlplus前缀显示当前用户
第一步:进入SQLPLUS的按照目录,cd $ORACLE_HOME/sqlplus/admin 第二步:查找ll vi glogin.sql 第三步:插入 命令行模式,Go, set sq ...
- LeetCode 15. 3Sum(三数之和)
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...