Как просмотреть SQL-запросы, выпущенные JPA?

Когда мой код вызывает такой вызов:

entityManager.find(Customer.class, customerID);

Как я могу увидеть запрос SQL для этого вызова? Предполагая, что у меня нет доступа к серверу базы данных для профилирования/мониторинга вызовов, существует ли способ зарегистрировать или просмотреть в моей среде IDE соответствующие SQL-запросы, выданные вызовами JPA? Я иду против SQL Server 2008 R2 с помощью драйвера jTDS.

Ответ 1

Параметры ведения журнала зависят от поставщика. Вы должны знать, какую реализацию JPA вы используете.

  • Hibernate (см. здесь):

    <property name = "hibernate.show_sql" value = "true" />
    
  • EclipseLink (см. здесь):

    <property name="eclipselink.logging.level" value="FINE"/>
    
  • OpenJPA (см. здесь):

    <property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
    
  • DataNucleus (см. здесь):

    Установите категорию журнала DataNucleus.Datastore.Native на уровень, например DEBUG.

Ответ 2

Кроме того, если вы используете EclipseLink и хотите вывести значения параметров SQL, вы можете добавить это свойство в файл persistence.xml:

<property name="eclipselink.logging.parameters" value="true"/>

Ответ 3

Если вы используете hibernate и logback в качестве своего регистратора, вы можете использовать следующее (отображаются только привязки, а не результаты):

<appender
    name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -
            %msg%n</pattern>
    </encoder>
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator>
            <expression>return message.toLowerCase().contains("org.hibernate.type") &amp;&amp;
                logger.startsWith("returning");</expression>
        </evaluator>
        <OnMismatch>NEUTRAL</OnMismatch>
        <OnMatch>DENY</OnMatch>
    </filter>
</appender>

org.hibernate.SQL = DEBUG печатает запрос

<logger name="org.hibernate.SQL">
    <level value="DEBUG" />
</logger>

org.hibernate.type = TRACE печатает привязки и обычно результаты, которые будут подавлены через настраиваемый фильтр

<logger name="org.hibernate.type">
    <level value="TRACE" />
</logger>

Вам нужна зависимость janino (http://logback.qos.ch/manual/filters.html#JaninoEventEvaluator):

<dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>janino</artifactId>
    <version>2.6.1</version>
</dependency>

Ответ 4

В EclipseLink для получения SQL для определенного запроса во время выполнения вы можете использовать API DatabaseQuery:

Query query = em.createNamedQuery("findMe"); 
Session session = em.unwrap(JpaEntityManager.class).getActiveSession(); 
DatabaseQuery databaseQuery = ((EJBQueryImpl)query).getDatabaseQuery(); 
databaseQuery.prepareCall(session, new DatabaseRecord());

String sqlString = databaseQuery.getSQLString();

Этот SQL будет содержать? для параметров. Чтобы получить SQL-перевод с аргументами, вам понадобится DatabaseRecord со значениями параметров.

DatabaseRecord recordWithValues= new DatabaseRecord();
recordWithValues.add(new DatabaseField("param1"), "someValue");

String sqlStringWithArgs = 
         databaseQuery.getTranslatedSQLString(session, recordWithValues);

Источник: Как получить SQL для запроса

Ответ 5

Чтобы просмотреть все SQL и параметры в OpenJPA, поместите эти два параметра в файл persistence.xml:

<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
<property name="openjpa.ConnectionFactoryProperties" value="PrintParameters=true" />

Ответ 6

Если вы хотите видеть точные запросы в целом с значениями параметров и возвращаемыми значениями, вы можете использовать прокси-драйвер jdbc. Он перехватит все вызовы jdbc и зарегистрирует их значения. Некоторые прокси:

  • log4jdbc
  • jdbcspy

Они могут также предоставить некоторые дополнительные функции, такие как измерение времени выполнения запросов и сбор статистики.

Ответ 7

Пример использования log4j (src\log4j.xml):

<?xml version="1.0" encoding="UTF-8" ?>

<appender name="CA" class="org.apache.log4j.AsyncAppender">
    <param name="BufferSize" value="512"/>
    <appender-ref ref="CA_OUTPUT"/>
</appender>
<appender name="CA_OUTPUT" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="[%p] %d %c %M - %m%n"/>
    </layout>
</appender>

<logger name="org.hibernate.SQL" additivity="false">
    <level value="DEBUG"/>
    <appender-ref ref="CA"/>
</logger>

<root>
    <level value="WARN"/>
    <appender-ref ref="CA"/>
</root>

Ответ 8

Кроме того, если вы используете WildFly/JBoss, установите уровень ведения журнала org.hibernate в DEBUG

Hibernate Logging in WildFly

Ответ 9

Если вы используете Spring Framework. Измените свой файл application.properties, как показано ниже

#Logging JPA Queries, 1st line Log Query. 2nd line Log parameters of prepared statements 
logging.level.org.hibernate.SQL=DEBUG  
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE  

#Logging JdbcTemplate Queries, 1st line Log Query. 2nd line Log parameters of prepared statements 
logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG  
logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE  

Ответ 11

Еще один хороший вариант, если у вас слишком много журналов и вы хотите поместить их только как временные System.out.println(), вы можете, в зависимости от того, что делает ваш провайдер:

CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<ExaminationType> criteriaQuery = criteriaBuilder.createQuery(getEntityClass()); 

/* For Hibernate */
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(org.hibernate.Query.class).getQueryString());

/* For OpenJPA */ 
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(org.apache.openjpa.persistence.QueryImpl.class).getQueryString());

/* For EclipseLink */
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(JpaQuery.class).getSQLString());

Ответ 12

С помощью Spring Boot просто добавьте: spring.jpa.show-sql = true в application.properties. Это покажет запрос, но без фактических параметров (вы увидите? Вместо каждого параметра).

Ответ 13

Во время исследовательской разработки и для того, чтобы сосредоточить ведение журнала отладки SQL на конкретном методе, который я хочу проверить, я украсил этот метод следующими инструкциями logger:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;

((ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.hibernate.SQL")).setLevel(Level.DEBUG);
entityManager.find(Customer.class, customerID);
((ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.hibernate.SQL")).setLevel(Level.INFO);

Ответ 14

Там файл с именем persistence.xml Нажмите Ctrl + Shift + R и найдите его, затем там место, написанное как showSQL.

Просто поставьте его как true

Я не уверен, что сервер должен быть запущен как режим отладки. Проверьте SQL, созданные на консоли.