Hibernateを使用するときにパラメーター値を含むクエリ文字列を印刷する方法


回答:


426

次のカテゴリのログを有効にする必要があります。

  • org.hibernate.SQL   - debug実行時にすべてのSQL DMLステートメントをログに記録するように設定します
  • org.hibernate.type- traceすべてのJDBCパラメータをログに記録するように設定

したがって、log4j構成は次のようになります。

# logs the SQL statements
log4j.logger.org.hibernate.SQL=debug 

# Logs the JDBC parameters passed to a query
log4j.logger.org.hibernate.type=trace 

1つ目は、hibernate.show_sql=true従来のプロパティと同等です。2つ目は、バインドされたパラメーターを出力します。

別のソリューション(非休止ベース)は、P6SpyのようなJDBCプロキシドライバーを使用することです。


11
これは便利です。しかし、これは実際のSQLクエリを示していません。
ニコラバルブレスコ2013

6
@Nicolasは真実ですが、クエリの直後に、バインドされたパラメーターを表示します。
Xtreme Biker 2013

2
私はgrails 2.4.4とhibernate 4を使用しています。log4j構成の変更は機能しませんでしたが、p6spyは機能しました。
Champ

11
Hibernate 5ではorg.hibernate.type.descriptor.sql.BasicBinderロガーを使用できます。ログオンを有効にすると、org.hibernate.type役に立たない情報が印刷されてしまいます...
csharpfolk

5
org.hibernate.typeそしてorg.hibernate.loader.hql、私がパラメータを表示するために機能しない
Dherik

75

便宜上、Logback(SLF4J)の同じ構成例を次に示します。

<appender name="SQLROLLINGFILE">
 <File>/tmp/sql.log</File>
 <rollingPolicy>
  <FileNamePattern>logFile.%d{yyyy-MM-dd}.log</FileNamePattern>
 </rollingPolicy>
 <layout>
  <Pattern>%-4date | %msg %n</Pattern>
 </layout>
</appender>

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

<logger name="org.hibernate.type" additivity="false" >
 <level value="TRACE" />
 <appender-ref ref="SQLROLLINGFILE" />
</logger>

sql.logの出力(例)は次のようになります。

2013-08-30 18:01:15,083 | update stepprovider set created_at=?, lastupdated_at=?, version=?, bundlelocation=?, category_id=?, customer_id=?, description=?, icon_file_id=?, name=?, shareStatus=?, spversion=?, status=?, title=?, type=?, num_used=? where id=?
2013-08-30 18:01:15,084 | binding parameter [1] as [TIMESTAMP] - 2012-07-11 09:57:32.0
2013-08-30 18:01:15,085 | binding parameter [2] as [TIMESTAMP] - Fri Aug 30 18:01:15 CEST 2013
2013-08-30 18:01:15,086 | binding parameter [3] as [INTEGER] -
2013-08-30 18:01:15,086 | binding parameter [4] as [VARCHAR] - com.mypackage.foo
2013-08-30 18:01:15,087 | binding parameter [5] as [VARCHAR] -
2013-08-30 18:01:15,087 | binding parameter [6] as [VARCHAR] -
2013-08-30 18:01:15,087 | binding parameter [7] as [VARCHAR] - TODO
2013-08-30 18:01:15,087 | binding parameter [8] as [VARCHAR] -
2013-08-30 18:01:15,088 | binding parameter [9] as [VARCHAR] - MatchingStep@com.mypackage.foo
2013-08-30 18:01:15,088 | binding parameter [10] as [VARCHAR] - PRIVATE
2013-08-30 18:01:15,088 | binding parameter [11] as [VARCHAR] - 1.0
2013-08-30 18:01:15,088 | binding parameter [12] as [VARCHAR] - 32
2013-08-30 18:01:15,088 | binding parameter [13] as [VARCHAR] - MatchingStep
2013-08-30 18:01:15,089 | binding parameter [14] as [VARCHAR] -
2013-08-30 18:01:15,089 | binding parameter [15] as [INTEGER] - 0
2013-08-30 18:01:15,089 | binding parameter [16] as [VARCHAR] - 053c2e65-5d51-4c09-85f3-2281a1024f64

2
これはOPの質問には答えていません。
ShadowGames

33

に変更hibernate.cfg.xml

<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>

「log4j.properties」にlog4j以下のエントリを含めます。

log4j.logger.org.hibernate=INFO, hb
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE

log4j.appender.hb=org.apache.log4j.ConsoleAppender
log4j.appender.hb.layout=org.apache.log4j.PatternLayout

おかげで、本当にうまくいきました。これらの設定により、SQLクエリの下にのようなパラメーターが追加されますbinding parameter [1] as [VARCHAR] - [1]
G.チャルディーニ

28

春のブーツが使用されている場合は、これを設定するだけです:

aplication.yml

logging:
  level:
    org.hibernate.SQL: DEBUG
    org.hibernate.type: TRACE

aplication.properties

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE

そして何も。

HTH


20

Log4JDBCは、適切パラメーターを使用してデータベースに送られる正確な SQL を出力する優れたソリューションであり、これを行わない最も一般的な回答ではありません。これの大きな利点の1つは、SQLをDBフロントエンドに直接コピーして、そのまま実行できることです。

http://log4jdbc.sourceforge.net/

https://code.google.com/p/log4jdbc-remix/

後者は、クエリ結果の表形式の表現も出力します。

クエリからの結果セットテーブルと一緒にパラメータが設定された生成されたSQLを示すサンプル出力:

5. insert into ENQUIRY_APPLICANT_DETAILS (ID, INCLUDED_IN_QUOTE, APPLICANT_ID, TERRITORY_ID, ENQUIRY_ID, ELIGIBLE_FOR_COVER) values (7, 1, 11, 1, 2, 0) 


10 Oct 2013 16:21:22 4953 [main] INFO  jdbc.resultsettable  - |---|--------|--------|-----------|----------|---------|-------|
10 Oct 2013 16:21:22 4953 [main] INFO  jdbc.resultsettable  - |ID |CREATED |DELETED |CODESET_ID |NAME      |POSITION |PREFIX |
10 Oct 2013 16:21:22 4953 [main] INFO  jdbc.resultsettable  - |---|--------|--------|-----------|----------|---------|-------|
10 Oct 2013 16:21:22 4953 [main] INFO  jdbc.resultsettable  - |2  |null    |null    |1          |Country 2 |1        |60     |
10 Oct 2013 16:21:22 4953 [main] INFO  jdbc.resultsettable  - |---|--------|--------|-----------|----------|---------|-------|

2016年の更新

最近では、log4jdbc-log4j2(https://code.google.com/archive/p/log4jdbc-log4j2/)をSLF4jとlogbackで使用しています。私のセットアップに必要なMavenの依存関係は次のとおりです。

<dependency>
    <groupId>org.bgee.log4jdbc-log4j2</groupId>
    <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
    <version>1.16</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>${logback.version}</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>$logback.version}</version>
</dependency>

ドライバーとDB URLは次のようになります。

database.driver.class=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
database.url=jdbc:log4jdbc:hsqldb:mem:db_name #Hsql
#database.url=jdbc:log4jdbc:mysql://localhost:3306/db_name 

私のlogback.xml構成ファイルは次のようになります。これにより、パラメーターを含むすべてのSQLステートメントと、すべてのクエリの結果セットテーブルが出力されます。

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

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <logger name="jdbc.audit" level="ERROR" />
    <logger name="jdbc.connection" level="ERROR" />
    <logger name="jdbc.sqltiming" level="ERROR" />
    <logger name="jdbc.resultset" level="ERROR" />

    <!-- UNCOMMENT THE BELOW TO HIDE THE RESULT SET TABLE OUTPUT -->
    <!--<logger name="jdbc.resultsettable" level="ERROR" /> -->

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

最後に、クラスパスのルートにlog4jdbc.log4j2.propertiesという名前のファイルを作成する必要がありました(例:Mevnプロジェクトのsrc / test / resourcesまたはsrc / main / resources)。このファイルには、以下の1行があります。

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator

上記は、ロギングライブラリによって異なります。詳細については、https: //code.google.com/archive/p/log4jdbc-log4j2のドキュメントを参照してください

出力例:

10:44:29.400 [main] DEBUG jdbc.sqlonly -  org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70)
5. select memberrole0_.member_id as member_i2_12_0_, memberrole0_.id as id1_12_0_, memberrole0_.id 
as id1_12_1_, memberrole0_.member_id as member_i2_12_1_, memberrole0_.role_id as role_id3_12_1_, 
role1_.id as id1_17_2_, role1_.name as name2_17_2_ from member_roles memberrole0_ left outer 
join roles role1_ on memberrole0_.role_id=role1_.id where memberrole0_.member_id=104 

10:44:29.402 [main] INFO  jdbc.resultsettable - 
|----------|---|---|----------|--------|---|-----|
|member_id |id |id |member_id |role_id |id |name |
|----------|---|---|----------|--------|---|-----|
|----------|---|---|----------|--------|---|-----|

1
こんにちは....これはクールに見えます....医師が私に注文したものだけです:) ...しかし、CLOB / BLOBもサポートしていますか?また、結果セットではなくクエリのみを表示することは可能です。-ありがとう:)
dev ray

1
構成の例を教えていただけますか?
grep、2014

実際、後者はクエリ結果の表形式の表現を出力します...つまり、その優れた機能にはlog4jdbc-remixが必要です。
メリトン2016年

このソリューションは、Hibernateがページング結果セットに対して生成する行番号の値を確認する必要がある私の状況に最適でした。トレースログにはクエリパラメータ値のみが表示されます。
Oliver Hernandez

@Alan Hayはネイティブクエリもログに記録しますか?
サヤンタン

9

カテゴリ行をlog4j.xmlに追加できます。

<category name="org.hibernate.type">
    <priority value="TRACE"/>
</category>

休止状態のプロパティを追加します。

<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>

7

次のプロパティと値をlog4jまたはlogback構成に追加します。

org.hibernate.sql=DEBUG
org.hibernate.type.descriptor.sql.BasicBinder=TRACE

5
org.hibernate.type.descriptor.sql.BasicBinderカテゴリは、すべてのパラメータ、例えば列挙型が含まれていません。したがって、すべてが必要なTRACE場合は、org.hibernate.typeグループ全体が本当に必要です。
seanf 14

私にとっては、Hibernate 4.3で動作します!さらに、出力が多すぎるため、完全なorg.hibernate.typeをトレースしません。ほとんどの場合、このソリューションで十分です。
cslotty 2016年

org.hibernate.type.descriptor.sql.BasicExtractorが結果セットをログに記録することに注意してください。そのため、大きなサイズのエントリがあると、Eclipseでコンソールにログインするときにアプリケーションがクラッシュする可能性さえあります。また、ファイルへのログインにも理想的ではないと思います。これが私がこのソリューションを好む理由です。これはHibernate 3でも機能します。列挙型に興味がある人は、org.hibernate.type = TRACEのときにそれらをログに記録する正確なクラスを試してください。次に、org.hibernate.type.xyz.TheClassThatLogsEnumParams = TRACEを設定します。
ゲーザ

7

この投稿で説明したように、datasource-proxyを使用してそれを行うことができます。

アプリケーションがdataSourceBeanを期待している場合(例:経由@Resource)、これは次のように構成できますdatasource-proxy

<bean id="actualDataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init"
  destroy-method="close">
    <property name="className" value="bitronix.tm.resource.jdbc.lrc.LrcXADataSource"/>
    <property name="uniqueName" value="actualDataSource"/>
    <property name="minPoolSize" value="0"/>
    <property name="maxPoolSize" value="5"/>
    <property name="allowLocalTransactions" value="false" />
    <property name="driverProperties">
        <props>
            <prop key="user">${jdbc.username}</prop>
            <prop key="password">${jdbc.password}</prop>
            <prop key="url">${jdbc.url}</prop>
            <prop key="driverClassName">${jdbc.driverClassName}</prop>
        </props>
    </property>
</bean>

<bean id="proxyDataSource" class="net.ttddyy.dsproxy.support.ProxyDataSource">
    <property name="dataSource" ref="testDataSource"/>
    <property name="listener">
        <bean class="net.ttddyy.dsproxy.listener.ChainListener">
            <property name="listeners">
                <list>
                    <bean class="net.ttddyy.dsproxy.listener.CommonsQueryLoggingListener">
                        <property name="logLevel" value="INFO"/>
                    </bean>
                    <bean class="net.ttddyy.dsproxy.listener.DataSourceQueryCountListener"/>
                </list>
            </property>
        </bean>
    </property>
</bean>

<alias name="proxyDataSource" alias="dataSource"/>

Hibernateの出力とdatasource-proxyの比較:

INFO  [main]: n.t.d.l.CommonsQueryLoggingListener - Name:, Time:1, Num:1, Query:{[select company0_.id as id1_6_, company0_.name as name2_6_ from Company company0_][]}
INFO  [main]: n.t.d.l.CommonsQueryLoggingListener - Name:, Time:0, Num:1, Query:{[insert into WarehouseProductInfo (id, quantity) values (default, ?)][19]}
INFO  [main]: n.t.d.l.CommonsQueryLoggingListener - Name:, Time:0, Num:1, Query:{[insert into Product (id, code, company_id, importer_id, name, version) values (default, ?, ?, ?, ?, ?)][phoneCode,1,-5,Phone,0]}

datasource-proxyクエリは、パラメータ値を含んでいて、あなたができるように、あなたも、カスタムJDBC文のインターセプタを追加することができます右のあなたの統合テストからN + 1つのクエリ問題をキャッチ


5

org.hibernate.typeロガーをオンにして、実際のパラメーターが疑問符にどのようにバインドされているかを確認します。


4

<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="logs/system.log" />
    <param name="Append" value="true" />
    <param name="ImmediateFlush" value="true" />
    <param name="MaxFileSize" value="200MB" />
    <param name="MaxBackupIndex" value="100" />

    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d %d{Z} [%t] %-5p (%F:%L) - %m%n" />
    </layout>
</appender>

<appender name="journaldev-hibernate" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="logs/project.log" />
    <param name="Append" value="true" />
    <param name="ImmediateFlush" value="true" />
    <param name="MaxFileSize" value="200MB" />
    <param name="MaxBackupIndex" value="50" />

    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d %d{Z} [%t] %-5p (%F:%L) - %m%n" />
    </layout>
</appender>

<logger name="com.journaldev.hibernate" additivity="false">
    <level value="DEBUG" />
    <appender-ref ref="journaldev-hibernate" />
</logger>

<logger name="org.hibernate" additivity="false">
    <level value="INFO" />
    <appender-ref ref="FILE" />
</logger>

<logger name="org.hibernate.type" additivity="false">
    <level value="TRACE" />
    <appender-ref ref="FILE" />
</logger>

<root>
    <priority value="INFO"></priority>
    <appender-ref ref="FILE" />
</root>


3

ソリューションは正しいですが、結果オブジェクトのすべてのバインディングもログに記録します。これを防ぐには、別のアペンダーを作成してフィルタリングを有効にすることが可能です。たとえば、次のようにします。

<!-- A time/date based rolling appender -->
<appender name="FILE_HIBERNATE" class="org.jboss.logging.appender.DailyRollingFileAppender">
    <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
    <param name="File" value="${jboss.server.log.dir}/hiber.log"/>
    <param name="Append" value="false"/>
    <param name="Threshold" value="TRACE"/>
    <!-- Rollover at midnight each day -->
    <param name="DatePattern" value="'.'yyyy-MM-dd"/>

    <layout class="org.apache.log4j.PatternLayout">
        <!-- The default pattern: Date Priority [Category] Message\n -->
        <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
    </layout>

    <filter class="org.apache.log4j.varia.StringMatchFilter">
        <param name="StringToMatch" value="bind" />
        <param name="AcceptOnMatch" value="true" />
    </filter>
    <filter class="org.apache.log4j.varia.StringMatchFilter">
        <param name="StringToMatch" value="select" />
        <param name="AcceptOnMatch" value="true" />
    </filter>  
    <filter class="org.apache.log4j.varia.DenyAllFilter"/>
</appender> 

<category name="org.hibernate.type">
  <priority value="TRACE"/>
</category>

<logger name="org.hibernate.type">
   <level value="TRACE"/> 
   <appender-ref ref="FILE_HIBERNATE"/>
</logger>

<logger name="org.hibernate.SQL">
   <level value="TRACE"/> 
   <appender-ref ref="FILE_HIBERNATE"/>
</logger>

3
**If you want hibernate to print generated sql queries with real values instead of question marks.**
**add following entry in hibernate.cfg.xml/hibernate.properties:**
show_sql=true
format_sql=true
use_sql_comments=true

**And add following entry in log4j.properties :**
log4j.logger.org.hibernate=INFO, hb
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE
log4j.appender.hb=org.apache.log4j.ConsoleAppender
log4j.appender.hb.layout=org.apache.log4j.PatternLayout

上記の行のsingle31をhibernate構成ファイルに追加する必要があります。そうすると、確実に機能します。自分が実践したことはいつも投稿しています。
Vijay Bhatt 2015

3

この答えは、質問に対する少しの相違です。場合によっては、実行時のデバッグ目的でのみSQLが必要です。その場合、エディターでデバッグを使用するより簡単な方法があります。

  • org.hibernate.loader.Loader.loadEntityBatchにブレークポイントを設定します(またはスタックまでナビゲートします);
  • 実行が一時停止されたら、変数this.sqlの値を調べます。

これはHibernate 3用です。他のバージョンで動作するかどうかはわかりません。


3

mysql jdbcドライバーはすでにこの要件を満たすのに便利です。少なくともjarバージョン> = mysql-connect-jar-5.1.6.jarが必要です

ステップ1:[ロガーとカスタムロギングを追加するためにjdbc.urlを構成する]

    jdbc.url=jdbc:mysql://host:port/your_db?logger=com.mysql.jdbc.log.Slf4JLogger&profileSQL=true&profilerEventHandler=com.xxx.CustomLoggingProfilerEventHandler

現在、slf4jロギングを使用しています。デフォルトのロギングがlog4jの場合、slf4jロギングを使用するには、slf4j-api、slf4j-log4j12の依存関係を追加する必要があります。

ステップ2:[カスタムログを書き込む]

package com.xxx;
import java.sql.SQLException;
import java.util.Properties;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.log.Log;

public class CustomLoggingProfilerEventHandler implements ProfilerEventHandler {
    private Log log;

    public LoggingProfilerEventHandler() {
    }

    public void consumeEvent(ProfilerEvent evt) {
            /**
             * you can only print the sql as        this.log.logInfo(evt.getMessage())
             * you can adjust your sql print log level with: DEBUG,INFO
             * you can also handle the message to meet your requirement
             */ 
            this.log.logInfo(evt);
    }

    public void destroy() {
        this.log = null;
    }

    public void init(Connection conn, Properties props) throws SQLException {
        this.log = conn.getLog();
    }

}

2

私はlog4jのためにこれが好きです:

log4j.logger.org.hibernate.SQL=trace
log4j.logger.org.hibernate.engine.query=trace
log4j.logger.org.hibernate.type=trace
log4j.logger.org.hibernate.jdbc=trace
log4j.logger.org.hibernate.type.descriptor.sql.BasicExtractor=error 
log4j.logger.org.hibernate.type.CollectionType=error 

ねえ-これはいいです。しかし、ここではクエリは?その後にパラメータ値が続きます。私は無限に多くのクエリを持っているので、SQLエディターにコピーして貼り付けるだけで実行できるものが必要です。このアプローチを使用してそれを行う方法はありますか?私はサードパーティのライブラリーに行きたくはありません。ありがとう:)
dev ray

ありがとう。サードパーティのソリューションを使用して直接休止状態にする必要がないことを望んでいましたが、他に選択肢はないと思います。
dev ray

2

ロギングは機能しますが、あなたが望んでいるわけではありませんか、少し前に欲しかったのですが、P6Spy完全に機能します

ここに実装する簡単なチュートリアルと同様にP6SpyのMKYONGチュートリアルがあります

私にとってそれは魅力のように働きました。

  1. P6Spyライブラリをダウンロード

「p6spy-install.jar」を取得します

  1. それを抽出する

解凍しp6spy-install.jar、ファイルを探しp6spy.jarし、spy.properties

  1. ライブラリの依存関係を追加する

p6spy.jarプロジェクトライブラリの依存関係に追加する

  1. P6Spyプロパティファイルを変更する

データベース構成ファイルを変更します。既存のJDBCドライバーをP6Spy JDBCドライバーに置き換える必要があります–com.p6spy.engine.spy.P6SpyDriver

オリジナルはMySQL JDBCドライバー– com.mysql.jdbc.Driver

<session-factory>
  <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.password">password</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mkyong</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="show_sql">true</property>
</session-factory>

P6Spy JDBCドライバーに変更– com.p6spy.engine.spy.P6SpyDriver

<session-factory>
  <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
  <property name="hibernate.connection.driver_class">com.p6spy.engine.spy.P6SpyDriver
  </property>
  <property name="hibernate.connection.password">password</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mkyong</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="show_sql">true</property>
</session-factory>
  1. P6Spyプロパティファイルの変更P6Spyプロパティファイルの 変更–spy.properties

real driver既存のMySQL JDBCドライバーに置き換えます

realdriver=com.mysql.jdbc.Driver

#specifies another driver to use
realdriver2=
#specifies a third driver to use
realdriver3=

ログファイルの場所の変更logfileプロパティでログファイルの場所を変更すると、すべてのSQLステートメントがこのファイルにログインします。

ウィンドウズ

logfile     = c:/spy.log

* nix

logfile     = /srv/log/spy.log
  1. “spy.properties”プロジェクトのクラスパスにコピー

“spy.properties”プロジェクトのルートフォルダーにコピーし、プロジェクトが「spy.properties」を見つけられることを確認してください“spy.properties”。そうしないと、ファイルが見つからないという例外が表示されます。


これは、ユニットテストから生成されたSQLをログに記録しようとしていたSpring Bootアプリケーションで、私にとって最も簡単な方法でした。Gradleにテスト依存関係を追加し(testCompile 'p6spy:p6spy:3.8.5')、application.ymlを調整して、spring.datasource.url = jdbc:p6spy:h2:mem:testdbとspring.datasource.driver-class-を設定しましたname = com.p6spy.engine.spy.P6SpyDriver、次にspy.propertiesを追加し、realdriver = org.h2.Driverと希望のパスに設定されたログファイルを追加します。結果のログファイルから完全なSQLを抽出することは簡単でした。唯一の問題は、H2が生成されたタイムスタンプ形式を好まなかったことでした。
Ken Pronovici

2

<appender name="console" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" 
      value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
    </layout>
</appender>

<logger name="org.hibernate" additivity="false">
    <level value="INFO" />
    <appender-ref ref="console" />
</logger>

<logger name="org.hibernate.type" additivity="false">
    <level value="TRACE" />
    <appender-ref ref="console" />
</logger>


これは質問とどのように関連していますか?
hotzst 2016年

2

Hibernate 4とslf4j / log4j2を使用して、log4j2.xml構成に以下を追加してみました。

<Logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="trace" additivity="false"> 
    <AppenderRef ref="Console"/> 
</Logger> 
<Logger name="org.hibernate.type.EnumType" level="trace" additivity="false"> 
    <AppenderRef ref="Console"/>
</Logger>

しかし成功せず。

私が通っていこのスレッド休止状態で使用されるJBossロギングフレームワークはSLF4Jてログインするために設定する必要があること。アプリケーションのVM引数に次の引数を追加しました。

-Dorg.jboss.logging.provider=slf4j

そしてそれは魅力のように働きました。


2

log4j.fileの以下のプロパティを設定してください:

log4j.logger.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

Hibernateプロパティ設定:

hibernate.show_sql=true

2

Wildfly(standalone.xml)を使用した開発の場合、これらのロガーを追加します。

<logger category="org.hibernate.SQL">
   <level name="DEBUG"/>
</logger>
<logger category="org.hibernate.type.descriptor.sql">
   <level name="TRACE"/>
</logger>

1

hibernate 3.2.xxを使用している場合

log4j.logger.org.hibernate.SQL=trace

の代わりに

log4j.logger.org.hibernate.SQL=debug 

1

これをログに記録できます:

net.sf.hibernate.hql.QueryTranslator

出力例:

2013-10-31 14:56:19,029 DEBUG [net.sf.hibernate.hql.QueryTranslator] HQL: select noti.id, noti.idmicrosite, noti.fcaducidad, noti.fpublicacion, noti.tipo, noti.imagen, noti.visible, trad.titulo, trad.subtitulo, trad.laurl, trad.urlnom, trad.fuente, trad.texto  from org.ibit.rol.sac.micromodel.Noticia noti join noti.traducciones trad where index(trad)='ca' and noti.visible='S' and noti.idmicrosite=985 and noti.tipo=3446

2013-10-31 14:56:19,029 DEBUG [net.sf.hibernate.hql.QueryTranslator] SQL: select noticia0_.NOT_CODI as x0_0_, noticia0_.NOT_MICCOD as x1_0_, noticia0_.NOT_CADUCA as x2_0_, noticia0_.NOT_PUBLIC as x3_0_, noticia0_.NOT_TIPO as x4_0_, noticia0_.NOT_IMAGEN as x5_0_, noticia0_.NOT_VISIB as x6_0_, traduccion1_.NID_TITULO as x7_0_, traduccion1_.NID_SUBTIT as x8_0_, traduccion1_.NID_URL as x9_0_, traduccion1_.NID_URLNOM as x10_0_, traduccion1_.NID_FUENTE as x11_0_, traduccion1_.NID_TEXTO as x12_0_ from GUS_NOTICS noticia0_ inner join GUS_NOTIDI traduccion1_ on noticia0_.NOT_CODI=traduccion1_.NID_NOTCOD where (traduccion1_.NID_CODIDI='ca' )and(noticia0_.NOT_VISIB='S' )and(noticia0_.NOT_MICCOD=985 )and(noticia0_.NOT_TIPO=3446 )

こんにちは...私はこのアプローチの例を見つけることができません。リファレンス/例/チュートリアルを提供していただけませんか。そしてそれはまだ最新バージョンやhibernate / log4jと同じですか、それともorg.hibernate.QueryTranslatorか何かになっていますか?ありがとう
dev ray

こんにちは...私はこれを試しましたが、これは保存または更新では機能しないようです。これは、hqlからsqlへの変換が機能する選択クエリでのみ機能すると思います
dev ray

1

Log4Jdbcプラグインが要件に最適です。それは以下を示しています

1. Complete SQL query being hit to the db
2. Parameter values being passed to the query
3. Execution time taken by each query

Log4Jdbcを構成するには、以下のリンクを参照してください-

https://code.google.com/p/log4jdbc/

1

Wiresharkを使用するまたは類似のものを。

上記の回答のどれも、パラメータ付きのSQLを適切に出力しないか、または苦痛です。これは、アプリケーションからOracle / Mysqlなどに送信されるすべてのsql /コマンドをクエリでキャプチャするWireSharkを使用して実現しました。


2
Log4JDBCはそうします。上記を参照。
アランヘイ

1

ここでの回答はすべて役に立ちますが、SpringアプリケーションコンテキストXMLを使用してセッションファクトリを設定している場合、log4j SQLレベル変数を設定すると、その方法の一部しか利用できないため、hibernate.show_sql変数も設定する必要がありますアプリコンテキスト自体で、Hibernateに実際に値の表示を開始させます。

ApplicationContext.xmlには以下が含まれます。

<property name="hibernateProperties">
            <value>
            hibernate.jdbc.batch_size=25
            ... <!-- Other parameter values here -->
            hibernate.show_sql=true
            </value>
 </property>

そして、あなたのlog4jファイルは必要です

log4j.logger.org.hibernate.SQL=DEBUG

1

Javaの場合:

CriteriaQuery(javax.persistence)の場合は、TypedQueryでクエリを変換します。

次に:

query.unwrap(org.hibernate.Query.class).getQueryString();


1
おかげで、クエリは出力されますが、使用したパラメータは出力されません。パラメータを出力する方法もありますか?
リズラン

0

Hibernateはクエリとそのパラメーター値を別の行に表示します。

スプリングブートでapplication.propertiesを使用していて、application.propertiesで以下の強調表示されているパラメーターを使用できる場合

  1. org.hibernate.SQLはクエリを表示します

    logging.level.org.hibernate.SQL = DEBUG

  2. org.hibernate.typeはすべてのパラメーター値を表示し、select、insert、およびupdateクエリでマップされます。logging.level.org.hibernate.type = TRACE

    • org.hibernate.type.EnumTypeは列挙型のパラメーター値を表示します

      logging.level.org.hibernate.type.EnumType = TRACE

      例::

      2018-06-14 11:06:28,217 TRACE [main] [EnumType.java : 321] Binding [active] to parameter: [1]
    • sql.BasicBinderはinteger、varchar、booleanタイプのパラメーター値を表示します

      logging.level.org.hibernate.type.descriptor.sql.BasicBinder = TRACE

      例::

      • 2018-06-14 11:28:29,750 TRACE [http-nio-9891-exec-2] [BasicBinder.java:65]バインディングパラメータ[1] as [BOOLEAN]-[true]
      • 2018-06-14 11:28:29,751 TRACE [http-nio-9891-exec-2] [BasicBinder.java:65]バインディングパラメータ[2] as [INTEGER]-[1]
      • 2018-06-14 11:28:29,752 TRACE [http-nio-9891-exec-2] [BasicBinder.java:65]バインディングパラメータ[3] as [VARCHAR]-[public]

1
これでも、クエリの制限オフセットの値は表示されません。
T3rm1

0

私にとって最も簡単な解決策は、通常のstringReplaceを実装してパラメーター入力をパラメーター値で置き換えることです(簡単にするために、すべてのパラメーターを文字列として扱います)。

 String debugedSql = sql;
 //then, for each named parameter
     debugedSql = debugedSql.replaceAll(":"+key, "'"+value.toString()+"'");
 //and finnaly
 println(debugedSql);

または定位置パラメーター(?)
実行可能なSQLをログに記録する場合は、null値や日付などの特定の値のタイプに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.