Skip to content

EventListenerHolder と EventSubscriber

概要

uroboroSQLでは、SQL実行時のイベントをリスニングするための仕組みとして、EventListenerHolderEventSubscriberを提供しています。これらを利用することで、SQL実行前後の処理をフックし、ロギングやメトリクス収集などのクロスカッティングな処理を実装できます。

EventListenerHolder

EventListenerHolderは、複数のEventSubscriberを管理するコンテナクラスです。SQL実行時のイベントを登録されたすべてのサブスクライバーに通知します。

主な機能

  • イベントサブスクライバーの登録・削除、イベントサブスクライバー一覧の取得
  • 登録されたすべてのサブスクライバーへのイベント通知
  • イベント処理の順序制御

EventSubscriber

EventSubscriberは、SQL実行時の各種イベントを受け取るためのインターフェースです。以下のようなイベントをハンドリングできます。

対応イベント

SQL実行関連

イベント説明
AfterInitializeExecutionContextExecutionContext初期化後
BeforeSetParameterパラメータ設定前
BeforeTransformSqlSQL変換前
BeforeParseSqlSQLパース前
AfterGetOutParameter出力パラメータ取得後
AfterCreatePreparedStatementPreparedStatement生成後
AfterCreateCallableStatementCallableStatement生成後
AfterSqlQuerySQLQuery実行後
AfterSqlUpdateSQLUpdate実行後
AfterSqlBatchSQLBatch実行後
AfterProcedureProcedure実行後

Entity操作関連

イベント説明
BeforeEntityQueryEntityQuery実行前
AfterEntityQueryEntityQuery実行後
BeforeEntityInsertEntityInsert実行前
AfterEntityInsertEntityInsert実行後
BeforeEntityUpdateEntityUpdate実行前
AfterEntityUpdateEntityUpdate実行後
BeforeEntityDeleteEntityDelete実行前
AfterEntityDeleteEntityDelete実行後
BeforeEntityBatchInsertEntityBatchInsert実行前
AfterEntityBatchInsertEntityBatchInsert実行後
BeforeEntityBatchUpdateEntityBatchUpdate実行前
AfterEntityBatchUpdateEntityBatchUpdate実行後
BeforeEntityBulkInsertEntityBulkInsert実行前
AfterEntityBulkInsertEntityBulkInsert実行後

トランザクション関連

イベント説明
AfterBeginTransactionトランザクション開始後
BeforeEndTransactionトランザクション終了前
BeforeCommitコミット前
AfterCommitコミット後
BeforeRollbackロールバック前
AfterRollbackロールバック後

uroboroSQLで提供されているサブスクライバー

uroboroSQLでは、以下のEventSubscriber実装が標準で提供されています。

SecretColumnEventSubscriber

DBアクセス時に機密カラムの値を暗号化/復号化するサブスクライバーです。
このサブスクライバーを使用することで、DBの暗号化の仕組みを利用せずにカラム単位での値の暗号化・復号化ができます。

主な機能:

  • Javaの暗号化の仕組み を使用して、指定カラムの暗号化・復号化を行います。
    • INSERT/UPDATE実行時に指定カラムの値を暗号化
    • SELECT実行時に指定カラムの値を復号化

機密カラムの命名

SecretColumnEventSubscriber では機密情報を格納するカラムをカラム名で特定します。
そのためカラム名が同一で、暗号化するカラムと暗号化しないカラムが混在している場合は対応できません。
機密情報を格納するカラムの名前は一意に識別できるような命名を行ってください。

WrapContextEventSubscriber

発行するSQL文字列の前後をラップするサブスクライバーです。

主な機能:

  • SQL発行をフックし、発行されるSQLの前後に文字列を付与します。主に検索SQLをページングに対応するために一律limit句やoffset句を追加するような用途を想定しています。

AuditLogEventSubscriber

SQL実行の監査ログを記録するためのサブスクライバーです。SQL実行前後の情報を構造化されたログとして出力します。
AuditLogは ログ名 : jp.co.future.uroborosql.event.auditlog に debugレベルで出力されます。

主な機能:

  • SQL実行時刻、実行時間の記録
  • 実行されたSQL文とバインドパラメータの記録
  • 実行結果(件数、エラー情報など)の記録

注意事項

AuditLogEventSubscriber で件数を取得するためにはResultSetの種類が ResultSet#TYPE_SCROLL_INSENSITIVE または ResultSet#TYPE_SCROLL_SENSITIVE である必要があります。
ResultSet#TYPE_FORWARD_ONLY の場合は 件数は常に -1 となります。

DebugEventSubscriber

開発時のデバッグ用ログを出力するサブスクライバーです。SQL実行の詳細な情報をコンソールに出力します。
デバッグ用ログは ログ名 : jp.co.future.uroborosql.event.debug に debugレベルとtraceレベルで出力されます。

主な機能:

  • トランザクション開始・終了の表示(debug)
  • バインドパラメータの詳細表示(debug)
  • 発行したSQL名の表示(debug)
  • 発行したSQL文の表示(trace)

DumpResultEventSubscriber

クエリ結果をダンプ形式で出力するサブスクライバーです。SELECT文の実行結果を表形式で見やすく表示します。
クエリ結果ダンプ結果ログは ログ名 : jp.co.future.uroborosql.event.dumpresult に debugレベルで出力されます。

主な機能:

  • クエリ結果の表形式表示

注意事項

DumpResultEventSubscriber によるクエリ結果の取得にはResultSetの種類が ResultSet#TYPE_SCROLL_INSENSITIVE または ResultSet#TYPE_SCROLL_SENSITIVE である必要があります。
ResultSet#TYPE_FORWARD_ONLY の場合もクエリ結果は出力されますが、このサブスクライバーが結果セットを先頭から最後まで読み進めるため、 処理後にはカーソルが末尾に到達し、アプリケーション側で同じ ResultSet を使った後続の検索・取得処理は行えなくなります(結果セットが消費されます)

ReplCommandLogEventSubscriber

REPL(対話型SQL実行環境)でのコマンド実行ログを記録するサブスクライバーです。
コマンド実行ログは ログ名 : jp.co.future.uroborosql.event.replcommand に debugレベルで出力されます。

主な機能:

  • REPLコマンドの実行履歴記録

カスタムEventSubscriberの作成

uroboroSQLでは、EventSubscriberインターフェースを実装することで、独自のイベント処理を追加できます。
ここでは、カスタムサブスクライバーを作成する方法を解説します。

基本的な実装手順

1. EventSubscriberインターフェースの実装

EventSubscriberを継承し、必要なイベントメソッドをオーバーライドします。

java
public class CustomEventSubscriber extends EventSubscriber {
    private static final Logger LOG = LoggerFactory.getLogger(CustomEventSubscriber.class);

    @Override
    public void initialize() {
        // EventSubscriberが提供する各イベントのリスナー登録用メソッドにリスナーを登録
		    afterSqlQueryListener(this::afterSqlQuery);
        // 初期化処理
        LOG.info("CustomEventSubscriber initialized");
    }

    void afterSqlQuery(final AfterSqlQueryEvent evt) {
        LOG.debug("Execute Query - sqlName:{} executed.", evt.getExecutionContext().getSqlName());
    }
}

2. SqlConfigへの登録

作成したサブスクライバーをSqlConfigに登録します。

java
SqlConfig config = UroboroSQL.builder("jdbc:h2:mem:test", "sa", "")
    .build();

config.getEventListenerHolder().addEventSubscriber(new CustomEventSubscriber());