Рубрики
Без рубрики

Лучший способ регистрации SQL-операторов с помощью JDBC, JPA или Hibernate

Автор оригинала: 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 .