Получить SQL-строку из запроса Hibernate
Мне нужно получить строку из запроса Hibernate и обработать ее позже (поэтому я не могу решить ее с помощью "hibernate.show_sql"
).
Я уже смотрел на Как получить SQL из Hibernate Criteria API (* не * для ведения журнала), но с этим обходным путем я получаю строку запроса SQL, но вместо того, чтобы показывать значение параметра, оно показывает '?'... Есть ли способ получить полную строку SQL со значениями параметров?
Я имею в виду, что с этим решением я получаю "SELECT * FROM USER WHERE NAME=? AND SURNAME=?"
но мне нужно получить "SELECT * FROM USER WHERE NAME='John' AND SURNAME='Doe'"
...
Идеи?
Ответы
Ответ 1
Существует инструмент под названием p6spy. Это немного старше, и я боюсь, что он больше не поддерживается. Во всяком случае, это дало мне хорошие результаты.
Изменить: только что обнаружил, что он активно развивается снова. Работает как очарование для меня!
Ответ 2
Вы должны установить TRACE
уровень ведения журнала в этот пакет спящего режима, а привязка параметров должна отображаться в журнале приложений:
<category name="org.hibernate.type">
<priority value="TRACE"/>
</category>
Пример вывода:
13:58:51,505 DEBUG [SQL]
insert
into
s.audit
(action, e_s, ip, time, userid, id)
values
(?, ?, ?, ?, ?, ?)
13:58:51,505 TRACE [StringType] binding 'Modify user' to parameter: 1
13:58:51,505 TRACE [StringType] binding 'E' to parameter: 2
13:58:51,505 TRACE [StringType] binding '164.20.81.65' to parameter: 3
13:58:51,505 TRACE [TimestampType] binding '2012-07-30 13:58:51' to parameter: 4
13:58:51,505 TRACE [IntegerType] binding '158' to parameter: 5
13:58:51,505 TRACE [IntegerType] binding '8851' to parameter: 6
И не забывайте, что свойство 'hibernate.show_sql=true'
, которое вы сказали ранее, чтобы показать также соответствующий SQL.
Ответ 3
Нет такой вещи, как "полная строка SQL со значениями параметров".
Hibernate использует подготовленные операторы, поэтому он отправляет строку запроса с ?
и значениями параметров в базу данных отдельно, так что фактический запрос никогда не строится.
Возможно, вы можете найти способ извлечь значения параметров из QueryImpl
, но даже в этом случае вы не сможете получить запрос, готовый к выполнению, потому что вам нужно обработать экранирование, преобразование значений параметров в SQL-литералы и т.д.
Ответ 4
JdbcLogger делает это вам. http://jdbclogger.sourceforge.net/. Поддерживает интеграцию mysql, postgres и spring.
Ответ 5
Другой вариант - использовать datasource-proxy, который позволяет прослушивать различные события JDBC, включая выполнение запроса.
Вы можете реализовать QueryExecutionListener.beforeQuery, который получает QueryInfo
с текстом запроса SQL и всеми параметрами.