2つのアプローチ

Javaコードからどのテーブルにどの操作を行っているかを把握するには、大きく2つの手段があります。 静的解析(ソースコードやクラスファイルを直接読む)と 動的解析(アプリを実行してSQLを観測する)です。

静的解析の仕組みと利点

静的解析では、Javaソースコードをパースして AST(Abstract Syntax Tree) に変換し、 文字列リテラルや定数フィールドを走査してSQL候補を取り出します。 実行環境が不要なため、CI/CDパイプラインに組み込むことも容易です。

✅ 実行不要
DBやアプリサーバーを起動しなくてもソースコードだけで解析できる。ビルド時やコードレビュー時に実行可能。
✅ 全コードパスを網羅
実行パスに依存せず、到達しにくい条件分岐の中のSQLも検出できる。
✅ フレームワーク非依存
MyBatis・JDBC・Spring JdbcTemplate——SQLが文字列として存在する限り、フレームワーク問わず対応できる。
⚠️ 動的SQL限界
実行時にStringBuilderで組み立てるSQLや、外部ファイル・DBから読み込むSQLは検出が困難。

動的解析の仕組みと利点

動的解析では、アプリケーションを実際に動かしてJDBCドライバーレベルでSQLをインターセプトする方法が代表的です。 P6Spy・Datasource-proxy などのライブラリを使うか、Java Agent でJDBC呼び出しをフックします。

✅ 実行時SQLを取得
動的に組み立てられたSQLも実際に発行された形で取得できる。バインドパラメータ展開後の文字列も見える。
✅ 高い精度
実際に実行されたSQLのみを対象とするため、誤検出が少ない。
⚠️ 実行環境が必要
DB接続・テストデータ・テスト実行環境がすべて必要。CIでの常時実行はコストが高い。
⚠️ カバレッジ依存
テストが通らないコードパスのSQLは検出できない。テストカバレッジが低いほど抜け漏れが増える。

比較表とトレードオフ

観点静的解析動的解析
実行環境 不要 必要(DB・テストデータ)
動的SQL対応 部分対応 完全対応
コードカバレッジ依存 なし あり
CI/CD組み込み 容易 可能だが重い
フレームワーク依存 なし JDBC層ならほぼなし
誤検出リスク 中(SQL以外の文字列を誤判定)

今回なぜ静的解析を選ぶか

このシリーズでは以下の理由から静的解析を採用します。

  • 実行環境なしで動く——ソースコードと依存ライブラリさえあれば結果を出せる
  • レガシーコードへの対応——古いシステムほどテスト環境が不十分で動的解析が難しい
  • CI統合のしやすさ——コードコミットのたびにCRUD図を更新できる
  • フレームワーク非依存——プレーンJDBC・独自ユーティリティでも解析可能

💡 2つを組み合わせるのが理想

静的解析で全コードパスを把握し、動的解析で実際に発行されたSQLを補完するハイブリッドアプローチが理想です。ただし本シリーズでは実用的な第一歩として静的解析に集中します。

ライブラリ選定

Java AST解析:JavaParser vs Eclipse JDT

ライブラリ特徴採用判断
JavaParser API がシンプル。Maven Central からすぐ使える。コミュニティが活発。 採用
Eclipse JDT Eclipse IDE が内部利用する高機能パーサー。セマンティック解析も可能だが依存が多い。 今回は不採用

SQL解析:JSqlParser vs 正規表現

手法特徴採用判断
JSqlParser SQL文をASTに変換。テーブル名の取得・操作種別の判別が確実で安全。 採用
正規表現 実装が速いが、JOINやサブクエリが絡むと抜け漏れやすい。メンテナンスしづらい。 シンプルな検証用のみ

設計の全体像

実装のフローは次のとおりです。

処理フロー
Javaソースファイル(*.java)
       ↓
[JavaParser] ASTに変換
       ↓
文字列リテラル・定数フィールドを走査
       ↓
SQL候補文字列を抽出
       ↓
[JSqlParser] SQL文をパース
       ↓
テーブル名 + 操作種別(C/R/U/D)を取得
       ↓
Map<クラス名, Map<テーブル名, Set<操作>>> に集約
       ↓
CRUD行列として出力(Markdown / Mermaid / PlantUML)

次の章では…

PART 03 では JavaParser を使ったAST走査の実装コードを一から作ります。依存関係の追加から、StringLiteralExpr を辿ってSQL候補を抽出するまでを丁寧に解説します。

→ PART 03 — SQL抽出の実装へ