`
lt200819
  • 浏览: 188966 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

灵活控制 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 可能配置很不相象了,需斟酌应对。

分享到:
评论

相关推荐

    hibernate-log4j日志

    2. **Appender**:Appender负责控制日志的输出目的地,例如控制台、文件或网络。常见的Appender类型有ConsoleAppender(输出到控制台)、FileAppender(写入文件)和WriterAppender(写入自定义流)。 3. **Layout*...

    hibernate3.3.1接口实现包 slf4j-log4j12-1.5.2

    这样,Hibernate的日志就会通过SLF4J-Log4j12进行输出,便于调试和问题排查。 **应用场景与优势** 通过整合Hibernate3.3.1和SLF4J-Log4j12-1.5.2,开发者可以方便地监控应用程序的运行状态,查看SQL执行情况,定位...

    spring hibernate ext项目

    1. 自定义注解:可能定义了一些自定义的Spring或Hibernate注解,以便于代码的组织和简化。 2. 工具类和实用方法:可能提供了对Spring和Hibernate常用操作的封装,提高开发效率。 3. 模块化设计:可能将不同的功能...

    jboss JAR包

    通过集成JBoss Logging,开发者可以方便地配置日志级别,控制输出哪些级别的日志信息,例如错误、警告、信息或者调试信息,从而更好地理解和优化应用程序的行为。 具体到使用HIBERNATE时,以下是一些关于JBoss ...

    HIbernate连接池配置总结基于第三方c3p0和proxool

    为了确保连接池的健康运行,可以启用连接池的监控和诊断功能,比如C3P0提供了日志输出和监控网页,便于查看连接池的状态,及时发现并解决问题。 总的来说,选择和配置适合的Hibernate连接池是优化数据库性能的关键...

    log4j-为文章提供下载资源

    log4j提供了灵活的配置方式,允许用户调整日志级别,控制输出信息的详细程度,以及选择将日志信息输出到控制台、文件、数据库或其他目的地。 **log4j核心组件** 1. **Logger**: 日志记录器,它是日志系统的核心,...

    图书管理系统修订版

    7. **异常处理与日志记录**:为了确保系统的稳定性和可维护性,开发者可能会使用Java的异常处理机制,并集成Log4j或SLF4J进行日志记录,便于追踪和诊断问题。 8. **单元测试与集成测试**:为了保证代码质量,项目...

    员工信息响应处理demo

    在这个demo中,可能会有用于创建、查询、更新和删除(CRUD)员工信息的SQL脚本或ORM(对象关系映射)框架,如Hibernate或MyBatis。 3. **前后端交互**:员工信息的响应处理通常通过API(应用程序编程接口)进行,...

    基于struts+hibernate+spring+easyui+mysql的网上商城项目实战源码.zip

    MySQL提供了一系列安全措施,如用户账户管理、访问权限控制、SSL/TLS加密连接、审计日志等功能,确保数据的安全性和合规性。同时,MySQL附带了一系列管理工具,如MySQL Server、MySQL Workbench、MySQL Shell等,...

    SSH架构整合的Dept、Emp的CRUD

    同时,通过集成如Log4j或SLF4J的日志框架,可以在控制台或日志文件中记录下操作的详细信息,以便于后期的调试和问题排查。 总的来说,“SSH架构整合的Dept、Emp的CRUD”项目展示了如何利用SSH框架进行数据库操作,...

    druid连接池与C3P0连接池jar包.rar

    5. **监控和日志**:启用Druid的监控功能,并根据需要配置日志输出,以便于分析和优化应用性能。 综上所述,Druid和C3P0都是优秀的数据库连接池实现,各有其特点和优势。在实际应用中,开发者应根据项目需求和团队...

    Java项目开发平台开发规范.doc

    2. Hibernate数据持久化技术:Hibernate是一个流行的Java ORM(对象关系映射)框架,它允许开发者使用Java对象来操作数据库,而无需编写SQL语句。Hibernate通过实体类、映射文件和Session接口等,实现了对象与数据库...

    java项目源码

    2. **数据库交互**:在项目中,可能会用到SQL数据库如MySQL,通过JDBC或ORM(Object-Relational Mapping)框架如Hibernate或MyBatis进行数据操作。ORM框架可以将Java对象和数据库表进行映射,简化数据访问层的代码。...

    WebSphere部署war项目

    - 在管理控制台中,配置日志输出选项,选择“文件记录”和“控制台故障诊断”,将日志输出设置为控制台,便于调试。在正式运行时,可以重新配置回文件记录。 3. **数据源配置**: - 进入JDBC配置,创建一个新的...

    JAVA SMART系统-系统框架设计与开发(源代码+论文).rar

    12. **日志管理**:如Log4j或SLF4J,用于记录系统运行时的日志信息,便于调试和问题排查。 13. **性能监控**:可能采用了如JMX(Java Management Extensions)或Spring Actuator等工具,对系统性能进行监控和诊断。...

    简单的酒店管理系统_java

    - 日志记录(如使用Log4j)帮助追踪和诊断问题,优化系统性能。 6. **测试**: - JUnit是Java中的单元测试框架,用于验证各个功能模块的正确性。 - Selenium或Appium可能用于进行UI自动化测试,确保用户界面的...

    单体架构项目开发(插入数据为例)的项目资源

    在这个项目中,你可能会看到如何使用SQL语句进行数据的插入操作,例如使用JDBC(Java Database Connectivity)或者ORM(对象关系映射)框架如Hibernate或MyBatis来执行插入操作。 2. RESTful API设计:为了使服务...

    spring 3 依赖包_part4

    在Spring中,合适的日志框架可以方便地记录应用程序的运行情况,帮助调试和诊断问题。 综上所述,这个压缩包包含了一系列与Spring 3.x项目开发密切相关的库,涵盖了测试、持久化、日期处理、HTTP服务器、XML处理、...

    DB重复使用模块

    对于开发和维护,模块可能提供测试工具和日志记录功能,帮助开发者诊断问题,确保代码质量。 总结来说,“DB重复使用模块”是一个集成了多种数据库操作功能的组件,它通过JDBC接口连接数据库,提供了连接池、事务...

    SCSystem.zip

    此外,ORM(Object-Relational Mapping)框架如Hibernate或MyBatis也可能被用来简化数据库操作,它们允许开发者用面向对象的方式来处理数据库交互,减少了手动编写SQL的需求。 SCSystem还可能涉及事务管理,这是...

Global site tag (gtag.js) - Google Analytics