Если мы посмотрим на конфигурацию hibernate , два свойства, hibernate.format_sql и hibernate.use_sql_comments, должны быть включены для печати выполненного кода SQL через консоль.
Это хорошее начало, но, похоже, нам нужно больше информации для точной диагностики производительности, такой как события соединения, возвращаемые данные по запросам или привязка параметров (в hibernate отображаются значения параметров со знаком вопроса ? ). Следовательно, нам нужен еще один способ проверки сгенерированного sql . Log4jdbc — это драйвер jdbc, который может регистрировать вызовы sql / jdbc . Фактически log4jdbc является реализацией шаблона прокси, который автоматически загружает популярные драйверы jdbc ( Oracle, Derby, MySql, PostgreSql, H2, Hsqldb ,…), перехватывает вызовы, регистрирует информацию, а затем отправляет данные в драйвер « spied ».
В log4jdbc есть 5 регистраторов, которые можно использовать в зависимости от данных для мониторинга:
- jdbc.sqlonly : логи, выполненные sql с обязательными аргументами, замененными связанными данными.
- jdbc.sqltiming : регистрирует, сколько времени потребовалось для выполнения sql .
- jdbc.audit : регистрирует все вызовы jdbc, за исключением ResultSets .
- jdbc.resultset : так же, как jdbc.audit плюс ResultsSets .
- jdbc.connection : регистрирует открытые и закрытые события подключения.
В этом посте мы увидим, как настроить log4jdbc-remix , форк log4jdbc , который кроме наследования возможностей log4jdbc также позволяет:
- jdbc.resultsettable : набор результатов журнала в табличном формате.
- настроить его как источник данных.
- доступно в репозитории maven ( log4jdbc отсутствует в репозиториях maven).
В этом примере мы будем использовать проект, созданный JPA Spring Template, который содержит две сущности Order и Item, связанные с отношением « один ко многим» , и один тест, который выполняет некоторые операции с базой данных.
Первое, что нужно сделать, это добавить в проект зависимости log4jdb-remix и slf4j-log4j12 :
01
02
03
04
05
06
07
08
09
10
11
|
< 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, чтобы набор результатов печатался в формате таблицы, а также показывалось время, необходимое для выполнения каждого запроса.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<? 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 > |
После настройки регистраторов запустите проверку и проверьте вывод
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
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 .
Оптимизация приложений гибернации может подразумевать прикосновение ко многим частям приложения (конфигурация JVM , ядро базы данных, сеть и т. Д.), Но один очень важный аспект, который нужно позаботиться, — это количество запросов, отправляемых в RDBMS (например, проблема N + 1), и Объем данных, которые извлекаются из базы данных (проблема проецирования) и log4jdbc-remix, идеально подходит для этой цели.
И последнее замечание: log4jdbc (- remix ) — это регистратор jdbc , поэтому его не нужно использовать только в приложениях гибернации , его можно использовать с любой средой, в которой используется источник данных .
Я хотел бы, чтобы эта библиотека помогла вам.
Продолжай учиться,
Ссылка: Зарегистрируйте операции JDBC с Log4jdbc от нашего партнера по JCG Алекса Сото в блоге One Jar To Rule All .