MyBatis は、内部の Log Factory を通してログ情報を出力します。この Log Factory は、ログ情報を次に挙げる実装のいずれかに委譲(delegate)します。
実際に使用されるのは、MyBatis 内部の Log Factory が検出した実装になります。MyBatis の Log Factory は上に挙げた順番でロギング実装を検索し、最初に見つけた実装を使用します。上記の実装が検出できなかった場合、ログは出力されません。
アプリケーションサーバーでは、出荷時のクラスパスに Commons Logging が含まれていることがよくあります(Tomcat や WebSphere は良い例でしょう)。重要なのは、このような環境では MyBatis は Commons Logging を使用するということです。これはつまり、独自の Commons Logging 実装を使う WebSphere のような環境では、あなたが追加した Log4J の設定は無視されるということを意味しています。この現象が厄介なのは、MyBatis が Log4J の設定を無視しているように見えるということです(実は、このような環境では MyBatis が Commons Loggin を使用するため、Log4J の設定が無視されているのです)。クラスパスに Commons Logging を含む環境で動作するアプリケーションでも、mybatis-config.xml に設定を追加することで別のロギング実装を使用することができます。
<configuration> <settings> ... <setting name="logImpl" value="LOG4J"/> ... </settings> </configuration>
指定可能な値は SLF4J, LOG4J, LOG4J2, JDK_LOGGING, COMMONS_LOGGING, STDOUT_LOGGING, NO_LOGGING ですが、org.apache.ibatis.logging.Log インターフェイスを実装し、コンストラクター引数として String を受け取る独自に実装したクラスの完全修飾クラス名を指定することもできます。
下記のメソッドを呼び出すことでロギング実装を指定することも可能です。
org.apache.ibatis.logging.LogFactory.useSlf4jLogging(); org.apache.ibatis.logging.LogFactory.useLog4JLogging(); org.apache.ibatis.logging.LogFactory.useJdkLogging(); org.apache.ibatis.logging.LogFactory.useCommonsLogging(); org.apache.ibatis.logging.LogFactory.useStdOutLogging();
これらのメソッドは、他の MyBatis のメソッドより前に呼び出す必要があります。また、要求された実装が実行時のクラスパスに含まれている場合にのみ切り替えることが可能です。例えば、Log4J に切り替えようとして、実行時に Log4J が見つからない場合、MyBatis は切り替えの要求を無視して通常のアルゴリズムでロギング実装を検索します。
SLF4J, Apache Commons Logging, Apache Log4J, JDK Logging API についての詳細はこのドキュメントの範囲外となりますが、後述の設定例は参考になると思います。これらのフレームワークについての詳しい情報は、以下の各サイトを参照してください。
実行されるステートメントのログを出力するためには、パッケージ、Mapper の完全修飾名、ネームスペース、あるいはステートメントの完全修飾名に対してログ出力を有効にしてください。
具体的な設定方法は使用するロギング実装によります。以下は Log4J での設定例です。ロギングサービスの設定は、単純にいくつかの設定ファイル(例えば log4j.properties)と、場合によっては新しい JAR(例えば log4j.jar)を追加するだけのことです。以下は、Log4J をプロバイダーとして完全なロギングサービスを設定する手順です。
Log4J を使うので、Log4J の JAR ファイルがアプリケーションから利用できるようにしておく必要があります。Log4J の JAR ファイルをダウンロードしてあなたのアプリケーションのクラスパスに追加してください。JAR ファイルは先ほど挙げた URL からダウンロードできます。
Web あるいはエンタープライズアプリケーションの場合は、ダウンロードした log4j.jar を WEB-INF/lib ディレクトリに追加します。スタンドアローンアプリケーションの場合は起動時の JVM 引数 -classpath に追加するだけです。
Log4J の設定はシンプルです。例えば次の Mapper のログを出力する場合:
package org.mybatis.example; public interface BlogMapper { @Select("SELECT * FROM blog WHERE id = #{id}") Blog selectBlog(int id); }
次のテキストを含む log4j.properties というファイルを作成し、クラスパスに配置します。
# Global logging configuration log4j.rootLogger=ERROR, stdout # MyBatis logging configuration... log4j.logger.org.mybatis.example.BlogMapper=TRACE # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
上記のように設定すると、Log4J は org.mybatis.example.BlogMapper について詳細なログを出力し、それ以外のクラスについてはエラーのみを出力します。
ログに出力される情報を細かく調整したいのなら、Mapper ファイル全体ではなく特定のステートメントを指定することもできます。
log4j.logger.org.mybatis.example.BlogMapper.selectBlog=TRACE
逆に、複数の Mapper に対するログを有効化したい場合もあるでしょう。その場合は、対象となる Mapper を含むパッケージを指定することができます。
log4j.logger.org.mybatis.example=TRACE
クエリが大量の結果セットを返すようなケースでSQLステートメントのみを出力したい場合に対応できるよう、SQLステートメントは DEBUG(JDK logging では FINE)レベル、結果は TRACE(JDK logging では FINER)レベルで出力されるようになっています。SQLステートメントのみを出力したい場合、ログレベルに DEBUG を設定します。
log4j.logger.org.mybatis.example=DEBUG
Mapper インターフェイスを使っていない場合、例えば次のような Mapper XML ファイルを使っていたらどうすれば良いのでしょうか。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="org.mybatis.example.BlogMapper"> <select id="selectBlog" resultType="Blog"> select * from Blog where id = #{id} </select> </mapper>
この場合、次のようにネームスペースを指定することでこの XML ファイル全体のログを有効化することができます。
log4j.logger.org.mybatis.example.BlogMapper=TRACE
特定のステートメントのみを対象とする場合は次のように指定します。
log4j.logger.org.mybatis.example.BlogMapper.selectBlog=TRACE
お気づきのように、Mapper インターフェイスと XML のどちらを使っている場合でも、設定方法に違いはありません。
NOTE SLF4J or Log4j 2 をお使いの場合、MyBatis のログは MYBATIS というマーカーで出力されます。
上記の log4j.properties の残りの部分はアペンダーの設定になっていますが、このドキュメントでは説明しません。Log4J のサイトを参照してください。あるいは、設定値を変更してみてどのような結果になるか試してみるのも良いでしょう。