シリーズ総括
このシリーズで実装したものを振り返ります。
| PART | 実装内容 | 使用ライブラリ |
|---|---|---|
| 03 | ASTを走査してSQL文字列を抽出 | JavaParser |
| 04 | SQL文字列からテーブル名・操作種別を取得 | JSqlParser |
| 05 | クラス横断でCRUD行列を構築 | Java標準 |
| 06 | Markdown・Mermaid・PlantUMLで出力 | Java標準 |
| 07 | サンプルプロジェクトで動作確認 | — |
フレームワーク非依存で動作し、DBやアプリケーションを起動せずにCRUD図を生成できる実用的なツールが完成しました。
静的解析の限界
動的SQL(StringBuilder)
sb.append("SELECT").append("FROM ").append(tableName) のように実行時にSQLを組み立てるコードは検出できない。外部ファイルのSQL
XMLやプロパティファイルに書かれたSQL(MyBatisのMapper XMLなど)はJavaパーサーでは取得できない。
変数経由のSQL
別クラスから渡された文字列変数の値が SQL の場合、追跡するためにはデータフロー解析が必要でスコープ外。
方言非対応
Oracle固有の
MERGE INTO・CONNECT BY など、JSqlParserが対応していない方言は例外になる。限界への対処法
| 課題 | 対処法 |
|---|---|
| 動的SQL(Builder/Format) | 部分的なSQL断片("FROM users" など)にもパターンマッチを適用し、テーブル名だけ取り出す簡易フォールバック実装を追加する |
| 外部XMLのSQL | MyBatisのMapper XML専用パーサーを別途作成し、同じ CrudMatrixAggregator に追加する |
| JSqlParser非対応方言 | CCJSqlParserUtil.parse() 失敗時に正規表現フォールバックを試みる |
| 高精度が必要な箇所 | p6spy等の動的解析と組み合わせてハイブリッドで対応する |
Gradleタスクへの組み込み
// build.gradle
task generateCrudDiagram(type: JavaExec) {
description = 'CRUD図を生成してdocs/に出力します'
group = 'documentation'
classpath = sourceSets.main.runtimeClasspath
mainClass = 'com.example.tools.Main'
// 引数: [srcRoot, outputDir]
args = [
project.file('src/main/java').absolutePath,
project.file('docs').absolutePath
]
}
// buildタスクに含めない場合は依存関係不要
// 含める場合:
// compileJava.finalizedBy generateCrudDiagram
./gradlew generateCrudDiagram
Mavenプラグインへの組み込み
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>generate-crud-diagram</id>
<phase>verify</phase>
<goals><goal>java</goal></goals>
<configuration>
<mainClass>com.example.tools.Main</mainClass>
<arguments>
<argument>${project.basedir}/src/main/java</argument>
<argument>${project.basedir}/docs</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
CI/CD統合のヒント
name: Update CRUD Diagram
on:
push:
paths:
- 'src/main/java/**'
jobs:
crud-diagram:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Generate CRUD Diagram
run: ./gradlew generateCrudDiagram
- name: Commit updated diagrams
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "docs: update CRUD diagram [skip ci]"
file_pattern: "docs/crud-*"
💡 docs/ をコミットする設計について
CRUD図を docs/ フォルダにコミットしておくことで、コードレビュー時に PR の差分として CRUD の変化を確認できます。「このPRでどのテーブルへのアクセスが追加・変更されたか」が一目でわかります。
次のステップ
MyBatis XML対応
Mapper XMLファイルのSQLも同じパイプラインで処理するパーサーを追加する。namespace属性でクラス名を特定できる。
Spring JPA対応
@Query アノテーションの value 属性にある JPQL/SQL を JavaParser で抽出する処理を追加する。
グラフDB連携
行列データを Neo4j や Amazon Neptune に投入し、「このテーブルを削除するクラスの呼び出しグラフ」などをCypher/Gremlinでクエリする。
差分検出
前回実行時のCRUD行列を保存しておき、今回との差分(新規アクセス・削除されたアクセス)をレポートする。
✅ シリーズ完走おめでとうございます
PART 01 から 08 まで読んでいただきありがとうございます。このシリーズで実装したツールは、フレームワークに縛られず、実行環境なしで動き、CI/CDに組み込める実用的な静的解析ツールです。ぜひ実際のプロジェクトで試してみてください。