SqlLogRegistryについて

概要

DBFluteを利用しているときにSqlLogRegistryを利用したい場合は、
アプリケーションで明示的に設定をONにして下さい。@{DBFlute-0.6.0より}

前提

SqlLogRegistryとは、Seasarが提供するライブラリで、直近に実行したSQL文を保持して提供します。
API仕様はこちら

ex) 直近に実行したSQLをSqlLogRegistryを使って取得
SqlLogRegistry registry = SqlLogRegistryLocator.getInstance();
if (registry != null) {// 存在しなければ設定がOFFになっている
    SqlLog sqlLog = registry.getLast();
    if (sqlLog != null) {// 存在しなければ直近でSQLが発行されていない
        String completeSql = sqlLog.getCompleteSql();
        ...
    }
}
		
これは、SQLの履歴をDBに残したい要件があった場合などに非常に役立ちます。
処理を中断せざるを得ないような例外を発生させる場合に、直近のSQLということで
例外メッセージに含んでもいいかも知れません。

SqlLogはThreadLocalに保持され、デフォルトでは最大3件保持されます。
SQL実行後にバインド変数を解決した表示用SQLをを組み立ててThreadLocalに保持します。

懸念

Seasar-2.4.19/20(執筆時点最新)において、このSqlLogRegistryの機能はデフォルトでONになっております。
また、このSqlLogRegistryの機能はCommonsLoggingのログレベルがDEBUGでなくても有効です。
これは何を意味するかと言うと、この機能を利用しないプロジェクトで何も意識していないと、
「SQL実行後にバインド変数を解決した表示用SQLをを組み立ててThreadLocalに保持」という処理が
本番環境においても実行され続けるということです。これはパフォーマンスを劣化させる1要因となります。
画面のリクエスト処理の場合はあまり気になりませんが、夜間バッチ処理においては省きたい処理です。

これをOFFにするためには、アプリケーションがOFFにすることを明示的に指定してなければなりません。
参考になるMLがこちら

ex) SqlLogRegistryを無効化する
		
SqlLogRegistryLocator.setInstance(null);
		
		
これを知らないと、知らずのうちにパフォーマンスが劣化している可能性があります。

DBFluteでは

この機能を必要としないプロジェクトの方が割合としては多いかと思われます。
DBFluteとしては、「知らずのうちにパフォーマンスが劣化」という状況は避けたいと考えております。
そこで、DBFluteではこの機能をデフォルトOFFにしています。@{DBFlute-0.6.0より}
「利用するプロジェクトが明示的に設定をONにしてSqlLogRegistryを利用する」という形にしています。

ex) DBFlute利用時にSqlLogRegistryを有効化する
		
SingletonS2ContainerFactory.init();
SqlLogRegistryLocator.setInstance(new SqlLogRegistryImpl());// Containerの初期化後に
		
		
その後、SqlLogRegistryの利用方法は先述した方法そのままです。

カスタマイズ

「直近のSQLを取得する」というより「発行したSQLを使ってなんらかのアクションをしたい(例えばDBに格納するとか)」場合は、SqlLogRegistryImplの代わりにアプリケーション独自のSqlLogRegistryを設定することでいくらでもカスタマイズが可能です。