JPAによって発行されたSQLクエリを表示する方法


155

私のコードが次のような呼び出しを発行すると:

entityManager.find(Customer.class, customerID);

この呼び出しのSQLクエリを確認するにはどうすればよいですか?呼び出しをプロファイル/監視するデータベースサーバーにアクセスできない場合、IDE内でJPA呼び出しによって発行された対応するSQLクエリを記録または表示する方法はありますか?jTDSドライバーを使用してSQL Server 2008 R2に反対します。


8
JPAプロバイダーとは何ですか?この設定はプロバイダー固有のものだと思います。
btiernay

@Sajeeは、axtavtの回答を承認済みとしてマークして、訪問者がこの回答に直接あなたの質問を案内できるようにしてください。
8bitjunkie 2018年

回答:


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

1
これらのプロパティはどこに設定する必要がありますか?
Alex Worden

34

また、EclipseLinkを使用していて、SQLパラメーター値を出力する場合は、このプロパティをpersistence.xmlファイルに追加できます。

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

intellijでバインディング値を取得する代替手段はありますか?
ヴィニシウスM

15

ロガーとして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>

15

TopLinkで実行時に特定のクエリの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)の1つです
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 2013年

7

OpenJPAですべてのSQLとパラメーターを表示するには、以下の2つのパラメーターを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 2014年

1

さらに、WildFly / JBossを使用している場合は、org.hibernateのロギングレベルをDEBUGに設定します。

WildFlyでのHibernate Logging


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ベースの実装では、パラメーター化されたクエリのクエリの一部としてパラメーターを表示しません。
ティムワー

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  

1

他の人に役立つと思うチートシートを作成しました。すべての例でformat_sql、ログに記録されたクエリを1行に保持したい場合(きれいに印刷しない場合)、プロパティを削除できます。

かなり標準出力に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


0

Hibernateを使用していません。私の知る限り、単なる古いJPAです。showSQLはHibernateプロパティのように見えます。私の場合はうまくいきますか?
Sajee

答えは「いいえ」のようです。ログにSQLが表示されません。
Sajee

1
Sajee、persistence.xmlでプロパティをどのように宣言しますか?
ゴンディム

0

Spring Bootを使用して、application.propertiesにspring.jpa.show-sql = trueを追加するだけです。これはクエリを表示しますが、実際のパラメーターはありません(各パラメーターの代わりに?が表示されます)。


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 config)を出力するためのEclipseLink:

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

-2

persistence.xmlというファイルがあります。Ctrl+ Shift + Rを押して検索すると、showSQLのような場所が作成されます。

それを真実にしてください

サーバーをデバッグモードで起動する必要があるかどうかはわかりません。コンソールで作成されたSQLを確認します。


これは、sqlステートメントが表示するパラメーターだけを表示するには不十分です。パラメータ用。
Ebuzer Taha KANAT 2017

1
「showSQLのようなもの」は答えではありません。とCtrl + Shift + R?IDEについての仮定を行いました。
8bitjunkie 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.