hibernate sql_记录Hibernate SQL

hibernate sql

有两种众所周知的在Grails中记录Hibernate SQL的方法。 一种是在DataSource.groovy添加logSql = true (在所有环境或每个环境的顶级块中)




dataSource {
   dbCreate = ...
   url = ...
   ...
   logSql = true
}

另一种是使用Log4j日志记录配置:

log4j = {
   ...
   debug 'org.hibernate.SQL'
}

logSql的问题在于它太简单了–它只是将SQL转储到stdout,没有选项可以查看为positional设置的值? 参数。 日志记录方法的可配置性更高,因为您可以根据需要登录控制台,但是可以使用Appender将日志记录配置到文件,仅用于这些消息的文件或选择的任何目标。

但是日志记录方法也存在问题–通过启用第二个Log4j类别

log4j = {
   ...
   debug 'org.hibernate.SQL'
   trace 'org.hibernate.type'
}

我们可以看到变量值,但是对于PreparedStatement ResultSet获取都可以看到它们,并且获取可能导致大量的日志文件充满无用的语句。 之所以LongType ,是因为Hibernate用于将Java类值存储和加载到数据库列(例如LongTypeStringType等)的“ Type”类位于org.hibernate.type包中,并(间接)扩展了org.hibernate.type.NullableType它确实记录在其nullSafeSetnullSafeGet方法。

因此,如果您拥有GORM域类

class Person {
   String name
}

然后保存一个实例

new Person(name: 'me').save()

您将看到如下输出:

DEBUG hibernate.SQL  - insert into person (id, version, name) values (null, ?, ?)
TRACE type.LongType  - binding '0' to parameter: 1
TRACE type.StringType  - binding 'me' to parameter: 2
DEBUG hibernate.SQL  - call identity()

以后运行查询以获取一个或多个实例时

def allPeople = Person.list()

您会看到这样的输出

DEBUG hibernate.SQL  - select this_.id as id0_0_, this_.version as version0_0_, this_.name as name0_0_ from person this_
TRACE type.LongType  - returning '1' as column: id0_0_
TRACE type.LongType  - returning '0' as column: version0_0_
TRACE type.StringType  - returning 'me' as column: name0_0_

这对于一个实例来说还不错,但是如果有多个结果,则每个结果都有一个块,每一列都包含一行。

昨天,我在SpringOne 2GX上的Hibernate演讲中谈到了这一点,并意识到应该可以创建一个自定义的Appender ,该Appender检查这些类的日志语句,而忽略ResultSet gets产生的语句。 令我惊讶的是,事实证明,在Grails 2.x中,一切都发生了变化,因为我们已从Hibernate 3.3升级到3.6,并且此问题已在Hibernate中得到解决。

上面的输出实际上来自我在2.1.1应用程序中获得意外输出之后创建的1.3.9项目。 这是我在2.1.1中看到的:

DEBUG hibernate.SQL  - 
    /* insert Person
        */ insert 
        into
            person
            (id, version, name) 
        values
            (null, ?, ?)

TRACE sql.BasicBinder  - binding parameter [1] as [BIGINT] - 0

TRACE sql.BasicBinder  - binding parameter [2] as [VARCHAR] - asd

DEBUG hibernate.SQL  -
    /* load Author */ select
        author0_.id as id1_0_,
        author0_.version as version1_0_,
        author0_.name as name1_0_
    from
        author author0_
    where
        author0_.id=?

TRACE sql.BasicBinder  - binding parameter [1] as [BIGINT] - 1

TRACE sql.BasicExtractor  - found [0] as column [version1_0_]

TRACE sql.BasicExtractor  - found [asd] as column [name1_0_]

因此,现在不再进行从类型的基类进行的所有日志记录,而是对其进行了重新设计以委托给org.hibernate.type.descriptor.sql.BasicBinderorg.hibernate.type.descriptor.sql.BasicExtractor 。 很好,因为现在我们可以将Log4j配置更改为

log4j = {
   ...
   debug 'org.hibernate.SQL'
   trace 'org.hibernate.type.descriptor.sql.BasicBinder'
}

吃我们的蛋糕也要吃 SQL将记录到可配置的Log4j目标,并且仅记录PreparedStatement集。

请注意,第二个示例中SQL看起来有所不同,这并不是因为Grails或Hibernate发生了变化,而是因为我始终在测试应用中启用SQL格式设置(带有format_sql )和注释(带有use_sql_comments ),因此当我启用日志记录时,它最终会变得更多可读性强,我忘了为1.3版应用程序这样做:

hibernate {
   cache.use_second_level_cache = true
   cache.use_query_cache = false
   cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
   format_sql = true
   use_sql_comments = true
}

参考:An Solipsists博客上,从我们的JCG合作伙伴 Burt Beckwith 记录Hibernate SQL

翻译自: https://www.javacodegeeks.com/2012/10/logging-hibernate-sql.html

hibernate sql

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值