Автор оригинала: Vlad Mihalcea.
Вступление
В этой статье я покажу вам лучший способ регистрации операторов SQL при использовании JDBC, JPA или Hibernate.
Всякий раз, когда вы используете платформу доступа к данным, которая автоматически генерирует инструкции от вашего имени, необходимо регистрировать все инструкции, чтобы обеспечить их эффективность, а также указать возможные последствия для производительности.
Ведение журнала в режиме гибернации
Hibernate определяет свойство конфигурации hibernate.show_sql
для включения ведения журнала. К сожалению, журналы отправляются в консоль, что очень затрудняет их надлежащую фильтрацию. Гораздо лучший подход-включить ведение журнала инструкций SQL с помощью адаптера журнала:
Поскольку Hibernate использует PreparedStatement(ы)
исключительно, значения параметров привязки недоступны, когда инструкция печатается в журнале:
o.h.SQL - insert into post (title, version, id) values (?, ?, ?)
Чтобы зарегистрировать значения параметров привязки JDBC, вам необходимо добавить другой регистратор:
Теперь вы получаете параметры привязки к:
o.h.SQL - insert into post (title, version, id) values (?, ?, ?) o.h.t.d.s.BasicBinder - binding parameter [1] as [VARCHAR] - [High-Performance Java Persistence] o.h.t.d.s.BasicBinder - binding parameter [2] as [INTEGER] - [0] o.h.t.d.s.BasicBinder - binding parameter [3] as [BIGINT] - [1]
Однако наиболее простым способом регистрации операторов SQL вместе со значениями параметров привязки во время выполнения является использование внешнего источника данных
прокси. Поскольку прокси-сервер перехватывает все выполнения операторов, значения параметров привязки также могут быть проанализированы и распечатаны.
Либо JDBC Драйвер
, либо Источник данных
должны быть проксированы для перехвата выполнения операторов и регистрации их вместе с фактическими значениями параметров. Помимо ведения журнала операторов, прокси-сервер JDBC может предоставлять другие сквозные функции, такие как обнаружение длительных запросов или прослушиватели выполнения пользовательских операторов.
Источник данных-прокси
Менее известная структура ведения журнала JDBC, datasource-proxy обеспечивает поддержку пользовательских прослушивателей выполнения инструкций JDBC. В Java EE не все серверы приложений позволяют настраивать внешний источник данных
, поскольку они полагаются на свои собственные пользовательские реализации , которые связывают предоставленный пользователем JDBC Драйвер
. Поскольку он может украшать только источник данных
, источник данных-прокси
может не подходить для всех сред Java EE.
С другой стороны, поддержка программной конфигурации соответствует подходу к настройке на основе Java, используемому большинством современных приложений Spring:
@Bean public DataSource dataSource() { SLF4JQueryLoggingListener loggingListener = new SLF4JQueryLoggingListener(); loggingListener.setQueryLogEntryCreator(new InlineQueryLogEntryCreator()); return ProxyDataSourceBuilder .create(actualDataSource()) .name(DATA_SOURCE_PROXY_NAME) .listener(loggingListener) .build(); }
В следующем примере источник данных-прокси
используется для регистрации пакетной вставки из трех подготовленных утверждений
. Хотя обычно пакет печатается в одной строке журнала, выходные данные были разделены на несколько строк, чтобы соответствовать текущему макету страницы.
Name:DATA_SOURCE_PROXY, Time:6, Success:True, Type:Prepared, Batch:True, QuerySize:1, BatchSize:3, Query:["insert into post (title, version, id) values (?, ?, ?)"], Params:[(Post no. 0, 0, 0), (Post no. 1, 0, 1), (Post no. 2, 0, 2)]
Теперь присутствуют не только значения параметров привязки, но и, поскольку они сгруппированы в целом, очень легко визуализировать механизм дозирования.
С поддержкой прослушивателя пользовательских операторов datasourceproxy
позволяет создавать средство проверки количества запросов для утверждения автоматически сгенерированного количества операторов и, следовательно, предотвращать проблемы с запросами N+1 на этапе разработки .
P6spy
P6Spy был выпущен в 2002 году, в эпоху, когда серверы приложений J2EE правили миром корпоративных систем. Поскольку серверы приложений Java EE не допускают программную Конфигурацию источника данных
, P6Spy поддерживает декларативный подход к конфигурации (через файл spy.properties
).
P6Spy предлагает поддержку проксирования как JDBC Драйвера
(который подходит для приложений Java EE), так и JDBC Источника данных
(поддерживается некоторыми контейнерами Java EE и обычной практикой для корпоративных приложений Spring).
Запуск предыдущего примера дает следующий результат (также было применено форматирование):
p6spy - 1448122491807|0|batch|connection 7| insert into post (title, version, id) values (?, ?, ?)| insert into post (title, version, id) values ('Post no. 0', 0, 0) p6spy - 1448122491807|0|batch|connection 7| insert into post (title, version, id) values (?, ?, ?)| insert into post (title, version, id) values ('Post no. 1', 0, 1) p6spy - 1448122491807|0|batch|connection 7| insert into post (title, version, id) values (?, ?, ?)| insert into post (title, version, id) values ('Post no. 2', 0, 2) p6spy - 1448122491812|5|statement|connection 7| insert into post (title, version, id) values (?, ?, ?)| insert into post (title, version, id) values ('Post no. 2', 0, 2)
В порядке их появления выходные данные строятся из следующих столбцов:
Отметка времени | Метка времени выполнения инструкции |
Время выполнения | Продолжительность выполнения инструкции (в миллисекундах) |
Категория | Категория текущего оператора (например, оператор, пакет) |
Соединение | Идентификатор подключения к базе данных (назначенный P6Spy) |
Первоначальное заявление | Исходное заявление, которое было перехвачено P6Spy |
Отформатированное заявление | Оператор со всеми заполнителями параметров заменен фактическими значениями привязки |
Первые три строки связаны с добавлением инструкций в пакет, в то время как четвертая строка регистрирует фактическое выполнение пакета (что также объясняет значение столбца время выполнения ).
Одной из очень полезных конфигураций является свойство обнаружение сбоев
, которое может обнаруживать длительные операторы.
Видео
Поскольку это очень интересная тема, я решил также записать видео. Наслаждайтесь просмотром!
Вывод
Регистрация инструкций является очень важным аспектом для уровня доступа к данным, и использование платформы JDBC statementinterceptor может использовать другие сквозные функции, такие как мониторинг выполнения инструкций или даже автоматическое обнаружение проблем с запросами N+1 .