JPA에서 발행 한 SQL 쿼리를 보는 방법은 무엇입니까?


155

내 코드가 다음과 같은 호출을 발행하면

entityManager.find(Customer.class, customerID);

이 호출에 대한 SQL 쿼리를 어떻게 볼 수 있습니까? 호출을 프로파일 링 / 모니터링하기 위해 데이터베이스 서버에 액세스 할 수 없다고 가정하면 JPA 호출에 의해 발행 된 해당 SQL 쿼리를 IDE에서 기록하거나 볼 수있는 방법이 있습니까? jTDS 드라이버를 사용하여 SQL Server 2008 R2에 반대합니다.


8
JPA 제공자 란 무엇입니까? 이 설정은 공급자마다 다릅니다.
btiernay

@Sajee axtavt의 답변을 수락 된 것으로 표시하여 방문자가 귀하의 질문에이 답변으로 바로 연결되도록 할 수 있습니까?
8bitjunkie

답변:


332

로깅 옵션은 공급자마다 다릅니다. 어떤 JPA 구현을 사용해야하는지 알아야합니다.

  • 최대 절전 모드 ( 여기 참조 ) :

    <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.


4
@Sajee :이 답변에 허용 된 답변임을 나타내는 체크 표시를해야합니다. Hibernate를 사용하여 나에게 효과적입니다. 이 답변을 승인하면 귀하와 답변자는 stackoverflow.com에서 더 많은 포인트와 더 많은 권한을 갖습니다.
LS

57
이 본문을 persistence.xml에 넣으면 몸매가 좋을 것입니다. 그것은 <properties> 노드 아래에있을 것입니다 ... 그것이 분명하다면 미안합니다. 어디에 넣을 지 혼란 스럽습니다.
SoftwareSavant

5
Hibernate 및 log4j를 사용할 때 "org.hibernate.SQL"로거를 DEBUG로 설정할 수도 있습니다 ( javalobby.org/java/forums/t44119.html )
MosheElisha

또한 <properties> 노드는 <persistence-unit> 내의 다른 모든 요소 아래에 있어야합니다. <3 XML.
Tom Spurling

1
이러한 속성은 어디에 설정해야합니까?
Alex Worden

34

또한 EclipseLink를 사용 중이고 SQL 매개 변수 값을 출력하려는 ​​경우이 특성을 persistence.xml 파일에 추가 할 수 있습니다.

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

intellij에서 바인딩 값을 얻는 대안이 있습니까?
Vinícius M

15

최대 절전 모드 및 로그 백을 로거로 사용하는 경우 다음을 사용할 수 있습니다 (결과가 아닌 바인딩 만 표시).

<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>

15

EclipseLink에서 런타임시 특정 쿼리에 대한 SQL을 가져 오려면 DatabaseQuery API를 사용할 수 있습니다.

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을 얻는 방법


recordWithValues ​​란 무엇입니까? DatabaseQuery 또는 EJBQueryImpl에서 가져올 수 있습니까?
zmeda

1
Record 인수는 쿼리 인수를 포함하는 (Record, XMLRecord) 중 하나입니다.
Tomasz

Query와 같은 것이 있으면 myQuery = entityManager.createNamedQuery ( "MyEntity.findMe"); myQuery.setParameter ( "param1", "someValue); myQuery에서 recordWithValues를 얻는 방법
zmeda

recordWithValues ​​생성을 포함하도록 내 답변을 업데이트했습니다.
Tomasz

JPA로 실행되지 않는 eclipseLink 크랩에 대해이 작업을 수행하는 방법을 알고 있습니까? (나는 그것이 정확히 무엇인지 모르지만 워크 벤치 응용 프로그램에서 매핑 클래스를 생성했습니다 .... 그러나 EM은 없지만 탑 링크 서비스 만 세션을 요청할 수는 있지만 쿼리는 알 수 없습니다. ReadAllQuery, ExpressionBuilder 및 Expression과 같은 클래스를 사용하십시오. 너무 명확하지 않은 경우 회신 할 필요가 없습니다 (프로의 전문가가 아니고 JPA에 익숙합니다) 48 시간 이내에이 의견을 삭제하고 더 명확한 질문을 시도합니다.)
JBA

7

OpenJPA에서 모든 SQL 및 매개 변수를 보려면 다음 두 매개 변수를 persistence.xml에 두십시오.

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

5

매개 변수 값과 반환 값을 사용하여 정확한 쿼리를 모두 보려면 jdbc 프록시 드라이버를 사용할 수 있습니다. 모든 jdbc 호출을 가로 채고 값을 기록합니다. 일부 프록시 :

  • log4jdbc
  • jdbcspy

또한 쿼리 실행 시간 측정 및 통계 수집과 같은 몇 가지 추가 기능을 제공 할 수도 있습니다.


4

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>


1
답을 좀 더 설명해주세요. 메인 섹션이 org.hibernate.SQL 섹션이라고 가정합니까?
JackDev

2

다른 사람들에게 유용하다고 생각되는 치트 시트를 만들었습니다. 모든 예 format_sql에서 기록 된 쿼리를 한 줄에 유지하려면 (예 : 인쇄하지 않음) 속성을 제거 할 수 있습니다 .

준비된 명령문의 매개 변수와 로깅 프레임 워크의 최적화 없이 SQL 출력을 표준 출력으로 출력하십시오 .

application.properties 파일:

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

application.yml 파일:

spring:
  jpa:
    show-sql: true
    properties:
      hibernate:
        format_sql: true

로깅 프레임 워크를 사용하여 준비된 명령문의 매개 변수로 SQL 쿼리 작성하십시오 .

application.properties 파일:

spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

application.yml 파일:

spring:
  jpa:
    properties:
      hibernate:
        format_sql: true
logging:
  level:
    org:
      hibernate:
        SQL: DEBUG
        type:
          descriptor:
            sql:
              BasicBinder: TRACE

로깅 프레임 워크를 사용하여 준비된 명령문의 매개 변수 없이 SQL 쿼리 를 작성하십시오 .

application.properties 파일:

spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG

application.yml 파일:

spring:
  jpa:
    properties:
      hibernate:
        format_sql: true
logging:
  level:
    org:
      hibernate:
        SQL: DEBUG

출처 (및 자세한 내용) : https://www.baeldung.com/sql-logging-spring-boot


1

또한 WildFly / JBoss를 사용하는 경우 org.hibernate의 로깅 레벨을 DEBUG로 설정하십시오.

WildFly에서 최대 절전 모드 로깅


1

로그가 너무 많고 일시적으로 만 저장하려는 경우 다른 좋은 옵션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());

openjpa 기반 구현에서는 매개 변수화 된 쿼리에 대한 쿼리의 일부로 매개 변수가 표시되지 않습니다.
timwaagh

1

Spring 프레임 워크를 사용하는 경우 아래와 같이 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  

0

나는 최대 절전 모드를 사용하지 않습니다. AFAIK, 평범한 오래된 JPA. showSQL은 Hibernate 속성처럼 보입니다. 제 경우에는 효과가 있습니까?
Sajee

대답은 아니오 인 것 같습니다. 로그에 SQL이 표시되지 않습니다.
Sajee

1
Sajee, persistence.xml에서 속성을 어떻게 선언합니까?
Gondim

0

Spring Boot를 사용하면 spring.jpa.show-sql = true를 application.properties에 추가하십시오. 쿼리가 표시되지만 실제 매개 변수는 표시되지 않습니다 (각 매개 변수 대신?가 표시됨).


0

탐구 적 개발 중에 확인하려는 특정 메소드에 대한 SQL 디버깅 로깅에 초점을 맞추기 위해 다음 로거 명령문으로 해당 메소드를 장식합니다.

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);

0

SQL (persistence.xml 구성)을 출력하는 EclipseLink :

<property name="eclipselink.logging.level.sql" value="FINE" />

-2

persistence.xml이라는 파일이 있습니다. Ctrl + Shift + R을 누르고 그것을 찾으면 showSQL과 같은 곳이 있습니다.

그냥 진실로 넣어

서버를 디버그 모드로 시작해야하는지 잘 모르겠습니다. 콘솔에서 작성된 SQL을 확인하십시오.


이것은 매개 변수를 표시하기에 충분하지 않습니다 sql statement only show? 매개 변수
Ebuzer Taha KANAT

1
"showSQL과 같은 것"은 답이 아닙니다. Ctrl + Shift + R? IDE에 대해 가정했습니다.
8bitjunkie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.