MirageのインストールとSLF4Jの設定
2WaySQLが使えるシンプルなデータベースアクセスライブラリーのMirageを使ってみました。
ソース自体は、ドキュメントにあるものに少し手を加えたものですが、ログ出力をSFL4Jにしたかったのでその点を調べてみました。
Mirageのインストール
ドキュメントの通り、pom.xmlを以下のようにします。今回はデータベースにH2を使うのでH2のJDBCドライバも一緒に入れておきます。
<repositories> <repository> <id>amateras</id> <name>Project Amateras Maven2 Repository</name> <url>http://amateras.sourceforge.jp/mvn/</url> </repository> </repositories> <dependencies> <dependency> <groupId>jp.sf.amateras.mirage</groupId> <artifactId>mirage</artifactId> <version>1.1.6</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.171</version> <scope>runtime</scope> </dependency> </dependencies>
H2の起動と準備
別途H2データベースを起動しておきます。導入はzipファイルをダウンロードします。
展開したディレクトリのbin/h2.shに実行権限を与え実行するとH2データベースが起動します。
$ chmod 744 h2.sh $ ./h2.sh
起動するとブラウザが立ち上がるのでそのまま接続します。JDBC URLやUser Name、PasswordはMirageから接続する際にも使用するのでメモしておきます。
Mirageのサイトにあるサンプルに近い形で動かしたいので以下のDDLでテーブルを作成します。
CREATE TABLE book( book_id INT, book_name VARCHAR(80), author VARCHAR(40), price INT, PRIMARY KEY(book_id) )
適当にデータをinsertします。
INSERT INTO book VALUES(1,'よくわかるMirage','テスト太郎',1980); INSERT INTO book VALUES(2,'基礎からのH2','H2花子',2000);
テーブルデータの読み込み
Mirageのサイトとほぼ同じものを作成します。
bookテーブルに対応したPOJOクラスのBookを作成します。
package com.example.mirage.mirageSample; import jp.sf.amateras.mirage.annotation.PrimaryKey; import jp.sf.amateras.mirage.annotation.PrimaryKey.GenerationType; public class Book { @PrimaryKey(generationType = GenerationType.APPLICATION) public Integer bookId; public String bookName; public String author; public Integer price; @Override public String toString() { return "Book [bookId=" + bookId + ", bookName=" + bookName + ", author=" + author + ", price=" + price + "]"; } }
データの取得もMirageのサンプル通りです。
package com.example.mirage.mirageSample; import java.util.List; import jp.sf.amateras.mirage.SqlManager; import jp.sf.amateras.mirage.session.Session; import jp.sf.amateras.mirage.session.SessionFactory; public class BookMain { public static void main(String[] args) { Session session = SessionFactory.getSession(); SqlManager sqlManager = session.getSqlManager(); session.begin(); try { BookParam param = new BookParam(); List<Book> result = sqlManager.getResultList(Book.class, "META-INF/selectBook.sql", param); for (Book book : result) { System.out.println(book); } session.commit(); } catch (Exception e) { e.printStackTrace(); session.rollback(); } finally { session.release(); } } }
実行するとコンソールに以下のように表示されます。
4 19, 2013 7:57:19 午後 jp.sf.amateras.mirage.session.JDBCSessionImpl begin 情報: Begin transaction. 4 19, 2013 7:57:19 午後 jp.sf.amateras.mirage.SqlExecutor printSql 情報: SELECT * FROM BOOK ORDER BY BOOK_ID ASC 4 19, 2013 7:57:19 午後 jp.sf.amateras.mirage.session.JDBCSessionImpl commit 情報: Commit transaction. 4 19, 2013 7:57:19 午後 jp.sf.amateras.mirage.provider.DefaultConnectionProvider releaseConnection 情報: Connection is released. Book [bookId=1, bookName=よくわかるMirage, author=テスト太郎, price=1980] Book [bookId=2, bookName=基礎からのH2, author=H2花子, price=2000]
最後の2行が今回のプログラムで記述した出力で、それ以外はMirageの内部的に出力しているログになります。今回の目的はこのログをSLF4J経由でLogbackに出力することになります。
SLF4J+Logbackでログを出力する
SLF4JとLogbackを使用するには、pom.xmlに以下の記述をします。
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.11</version> </dependency>
実際には、logback-classicの他に、logback-core、slf4j-apiも必要ですが、logback-classicを入れると一緒に入ります。
次に、ログ出力の設定を記述します。ファイルはクラスパスのルートにlogback.xmlというファイルを置きます。この辺りはいろいろルールがあるのでドキュメントを参照してください。以下の設定は、コンソールにinfo以上のレベルのログを出力します。
<configuration> <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> </appender> <root level="info"> <appender-ref ref="STDOUT" /> </root> </configuration>
最後に、ログ出力のコードを追加します。
最初にロガーを取得します。
private static final Logger logger = LoggerFactory.getLogger(BookMain.class);
System.outしていた部分をloggerで置き換えます。
logger.info(book.toString());
実行するとコンソールの出力が以下のように変わります。
4 19, 2013 9:36:16 午後 jp.sf.amateras.mirage.session.JDBCSessionImpl begin 情報: Begin transaction. 4 19, 2013 9:36:17 午後 jp.sf.amateras.mirage.SqlExecutor printSql 情報: SELECT * FROM BOOK ORDER BY BOOK_ID ASC 2013.04.19 21:36:17.054 [main] INFO c.e.mirage.mirageSample.BookMain - Book [bookId=1, bookName=よくわかるMirage, author=テスト太郎, price=1980] 2013.04.19 21:36:17.058 [main] INFO c.e.mirage.mirageSample.BookMain - Book [bookId=2, bookName=基礎からのH2, author=H2花子, price=2000] 4 19, 2013 9:36:17 午後 jp.sf.amateras.mirage.session.JDBCSessionImpl commit 情報: Commit transaction. 4 19, 2013 9:36:17 午後 jp.sf.amateras.mirage.provider.DefaultConnectionProvider releaseConnection 情報: Connection is released.
2013.04.19という文字列から始まっている行が今回Logbackで出力したログになります。Mirageのログは最初に行ったときと同じままということがわかります。
次に、このMirageのログもLogbackから出力するように設定をしてみます。
JDKのログをSLF4J経由でLogbackへ出力する
MirageのログはJDK標準のLoggerから出力されています。JDK標準のログ出力については、Java Logging APIを参照ください。
JDKのログをSLF4Jに移譲するためにはブリッジを使います。Mavenに以下の設定を追加して、JDKのログ→SLF4Jのブリッジを準備します。
<dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.4</version> </dependency>
これだけだとまだ、ログの移譲はできていません。以下の2つのうちのいずれかの設定をする必要があります。
この辺りは、SLF4Jのドキュメントにも詳しく記載されています。
まず1点目ですが、プログラムからブリッジの設定をします。mainメソッドの先頭に以下の行を追加します。
SLF4JBridgeHandler.removeHandlersForRootLogger(); // (since SLF4J 1.6.5)
SLF4JBridgeHandler.install();
2つ目は設定ファイルの記述でブリッジの設定ができます。設定ファイルは起動時のVMオプションにその場所を指定します。設定しない場合には、デフォルトのファイルが使用されます。
-Djava.util.logging.config.file=src/main/resources/logging.properties
デフォルトの設定ファイルは、以下の場所になります。
$JAVA_HOME/jre/lib/logging.properties
デフォルトの設定ファイルを変更すると同じJDKを使用するすべてのシステムに影響をおよぼすので、注意が必要です。
ファイル自体は以下の内容です。
handlers = org.slf4j.bridge.SLF4JBridgeHandler
プログラムで設定しても、ファイルで設定しても結果は同じで、以下のようにすべてのログがSLF4Jを通して、Logbackに出力されます。
2013.04.19 22:30:57.209 [main] INFO j.s.a.mirage.session.JDBCSessionImpl - Begin transaction. 2013.04.19 22:30:57.418 [main] INFO jp.sf.amateras.mirage.SqlExecutor - SELECT * FROM BOOK ORDER BY BOOK_ID ASC 2013.04.19 22:30:57.446 [main] INFO c.e.mirage.mirageSample.BookMain - Book [bookId=1, bookName=よくわかるMirage, author=テスト太郎, price=1980] 2013.04.19 22:30:57.446 [main] INFO c.e.mirage.mirageSample.BookMain - Book [bookId=2, bookName=基礎からのH2, author=H2花子, price=2000] 2013.04.19 22:30:57.446 [main] INFO j.s.a.mirage.session.JDBCSessionImpl - Commit transaction. 2013.04.19 22:30:57.447 [main] INFO j.s.a.m.p.DefaultConnectionProvider - Connection is released.