jdbc:log4jdbc
如果我们对Hibernate配置进行概述,则应启用两个属性hibernate.format_sql和hibernate.use_sql_comments,以通过控制台打印执行的sql代码。
这是一个好的开始,但似乎我们需要更多信息来准确诊断性能,例如连接事件,查询返回的数据或参数绑定( Hibernate显示带问号?的参数值)。 因此,我们需要另一种检查生成的sql的方法 。 Log4jdbc是一个jdbc驱动程序,可以记录sql / jdbc调用。 实际上, log4jdbc是代理模式的实现,它将自动加载流行的jdbc驱动程序( Oracle,Derby,MySql,PostgreSql,H2,Hsqldb等),拦截调用,记录信息,然后将数据发送到“ 间谍 ”驱动程序。
在log4jdbc中 ,根据要监视的数据,可以使用5个记录器:
- jdbc.sqlonly :使用绑定参数替换为绑定数据来记录执行的sql 。
- jdbc.sqltiming :记录执行一条SQL所花费的时间。
- jdbc.audit :记录除ResultSets之外的所有jdbc调用。
- jdbc.resultset :与jdbc.audit以及ResultsSets相同。
- jdbc.connection :记录打开和关闭连接事件。
在本文中,我们将了解如何配置log4jdbc-remix ,这是log4jdbc的分支 ,除了继承log4jdbc功能之外,还可以让我们:
- jdbc.resultsettable :以表格式记录结果集。
- 将其配置为数据源。
- 在Maven存储库中可用(在Maven存储库中不存在log4jdbc )。
对于此示例,我们将使用由JPA Spring模板创建的项目,该项目包含两个与一对多关系相关联的实体Order和Item ,以及一个执行一些数据库操作的测试。
首先要做的是将log4jdb-remix和slf4j-log4j12依赖项添加到项目中:
<dependency>
<groupId>org.slf4j<groupId>
<artifactId>slf4j-log4j12<artifactId>
<version>1.6.4<version>
<dependency>
<dependency>
<groupId>org.lazyluke<groupId>
<artifactId>log4jdbc-remix<artifactId>
<version>0.2.7<version>
<dependency>
接下来要做的是配置活动记录器。 根据我们要监视的数据,我们激活所需的记录器。 作为示例,让我们配置log4j.xml,以便以表格式打印结果集,并显示执行每个查询所花费的时间。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE log4j:configuration SYSTEM 'log4j.dtd'>
<log4j:configuration xmlns:log4j='http:jakarta.apache.orglog4j'>
<appender name='console-log4jdbc' class='org.apache.log4j.ConsoleAppender'>
<param name='Target' value='System.out' >
<layout class='org.apache.log4j.PatternLayout'>
<param name='ConversionPattern' value='%m%n' >
<layout>
<appender>
<!-- <logger name='jdbc.sqlonly' additivity='false'> -->
<!-- <level value='debug' > -->
<!-- <appender-ref ref='console-log4jdbc' > -->
<!-- <logger> -->
<logger name='jdbc.sqltiming' additivity='false'>
<level value='info' >
<appender-ref ref='console-log4jdbc' >
<logger>
<!-- <logger name='jdbc.connection' additivity='false'> -->
<!-- <level value='info' > -->
<!-- <appender-ref ref='console-log4jdbc' > -->
<!-- <logger> -->
<!-- log4jdbc option log the jdbc results as a table -->
<logger name='jdbc.resultsettable' additivity='false'>
<level value='info' >
<appender-ref ref='console-log4jdbc' >
<logger>
<log4j:configuration>
配置记录器后,运行测试并检查输出
create table Item (id bigint generated by default as identity, price double not null, product
varchar(255), quantity integer not null, order_id bigint, primary key (id)) {executed in 10 msec}
create table T_ORDER (id bigint generated by default as identity, customer varchar(255), primary
key (id)) {executed in 1 msec}
alter table Item add constraint FK22EF339F325255 foreign key (order_id) references T_ORDER
{executed in 11 msec}
insert into T_ORDER (id, customer) values (null, NULL) {executed in 1 msec}
insert into Item (id, order_id, price, product, quantity) values (null, NULL, 0.0, NULL, 0)
{executed in 0 msec}
batching 1 statements: 0: update Item set ORDER_ID=1 where id=1 {executed in 2 msec}
insert into T_ORDER (id, customer) values (null, NULL) {executed in 0 msec}
insert into Item (id, order_id, price, product, quantity) values (null, NULL, 0.0, NULL, 0)
{executed in 0 msec}
batching 1 statements: 0: update Item set ORDER_ID=2 where id=2 {executed in 0 msec}
select order0_.id as id1_0_, order0_.customer as customer1_0_ from T_ORDER order0_ where order0_.id=2
{executed in 0 msec}
|---------|---------|
|ID |CUSTOMER |
|---------|---------|
|[unread] |null |
|---------|---------|
select items0_.ORDER_ID as ORDER5_1_2_, items0_.id as id2_, items0_.id as id0_1_, items0_.order_id
as order5_0_1_, items0_.price as price0_1_, items0_.product as product0_1_, items0_.quantity
as quantity0_1_, order1_.id as id1_0_, order1_.customer as customer1_0_ from Item items0_ left
outer join T_ORDER order1_ on items0_.order_id=order1_.id where items0_.ORDER_ID=2 {executed in 0 msec}
|---------|---|---|---------|------|--------|---------|---|---------|
|ORDER_ID |ID |ID |ORDER_ID |PRICE |PRODUCT |QUANTITY |ID |CUSTOMER |
|---------|---|---|---------|------|--------|---------|---|---------|
|2 |2 |2 |2 |0.0 |null |0 |2 |[unread] |
|---------|---|---|---------|------|--------|---------|---|---------|
insert into T_ORDER (id, customer) values (null, NULL) {executed in 0 msec}
insert into Item (id, order_id, price, product, quantity) values (null, NULL, 0.0, 'foo', 0)
{executed in 0 msec}
batching 1 statements: 0: update Item set ORDER_ID=3 where id=3 {executed in 0 msec}
select order0_.id as id1_, order0_.customer as customer1_ from T_ORDER order0_ inner join Item
items1_ on order0_.id=items1_.ORDER_ID where items1_.product='foo' limit 2 {executed in 6 msec}
|---|---------|
|ID |CUSTOMER |
|---|---------|
|3 |null |
|---|---------|
select items0_.ORDER_ID as ORDER5_1_2_, items0_.id as id2_, items0_.id as id0_1_, items0_.order_id
as order5_0_1_, items0_.price as price0_1_, items0_.product as product0_1_, items0_.quantity
as quantity0_1_, order1_.id as id1_0_, order1_.customer as customer1_0_ from Item items0_ left
outer join T_ORDER order1_ on items0_.order_id=order1_.id where items0_.ORDER_ID=3 {executed in 0 msec}
|---------|---|---|---------|------|--------|---------|---|---------|
|ORDER_ID |ID |ID |ORDER_ID |PRICE |PRODUCT |QUANTITY |ID |CUSTOMER |
|---------|---|---|---------|------|--------|---------|---|---------|
|3 |3 |3 |3 |0.0 |foo |0 |3 |[unread] |
|---------|---|---|---------|------|--------|---------|---|---------|
输出以一种时尚的格式打印,查询包含绑定参数(不是问号(?)),并且还通知了处理时间。
请注意,记录或多或少的信息仅是配置日志的问题。 此外,根据日志级别,将在每种情况下提供或多或少的信息。 如果在DEBUG中配置了记录器,则将包括执行该sql的类名和行号(如果有)。 在INFO中将仅包含sql ,最后包含ERROR ,如果发生任何SQLException则显示堆栈跟踪。
优化Hibernate应用程序可能意味着接触到应用程序的许多部分( JVM配置,数据库引擎,网络等),但是要注意的一个非常重要的方面是发送到RDBMS的查询数量(例如N + 1问题),以及从数据库中检索到的数据量(投影问题)和log4jdbc-remix完全适合于此目的。
作为最后一点,log4jdbc( - 混音 )是一个JDBC记录,所以没有必要只在Hibernate应用程序使用,可以与任何框架一起使用,使用一个数据源 。
希望该库对您有所帮助。
保持学习,
参考:来自JCG合作伙伴 Alex Soto的Log4jdbc记录JDBC操作,位于One Jar To Rule Them All博客上。
翻译自: https://www.javacodegeeks.com/2012/05/log-jdbc-operations-with-log4jdbc.html
jdbc:log4jdbc