p6spy

アプリケーションが実行するSQLを把握する方法を考える。Statementだけなら簡単だがPreparedStatement/CallableStatementをどうするかが問題。自分でログ出力機能付のラッパークラスを作るのもいいが、まじめにやると大変そう。

もうひとつはp6spyみたいなソフトを使うことか。

http://sourceforge.net/projects/p6spy/

これの仕組みはおもしろい。アプリケーション側では使うJDBCドライバをp6spyの"com.p6spy.engine.spy.P6SpyDriver"にして、本当に使うドライバ名はプロパティファイル(p6.properties)に書いておく。そうすると

[ AP ] <-> [ p6spy ] <-> [ JDBC Driver ] <-> [ DB]

という格好になり、SQLを捕まえることができる。JFrameベースのJavaアプリとTomcat5のサーブレットで実行するSQLをファイルへ出力させることはできた。

しかし問題もある。このp6spyはLog4Jのアペンダを指定すればそちらへログを出力できるが、JDBCAppender(org.apache.log4j.jdbc.JDBCAppender)にすると、JDBCドライバの取り合い(?)が起きるようだ。これを回避するためにderegisterdriversというパラメータが用意されているがこれをtrueにするとスタックオーバーフロー。仮にこの問題が解決できたとしてもp6spyが渡すSQL文に'(シングルクォート)が含まれているとJDBCAppenderでエラーが起きる。これは適切にエスケープしてないから。さらにJDBCAppenderはStatementを使っているため性能的に懸念がある。