操作記号の定義

操作種別セット(例:[C, R, U])を表示文字列に変換するヘルパーを定義します。 順序は必ず C → R → U → D で統一します。

Java — 操作種別を文字列に変換
import java.util.*;
import static java.util.EnumSet.copyOf;

public class CrudRenderer {

    private static final List<CrudClassifier.CrudOp> ORDER =
        List.of(CrudClassifier.CrudOp.C, CrudClassifier.CrudOp.R,
                CrudClassifier.CrudOp.U, CrudClassifier.CrudOp.D);

    /** {C,R,U,D} → "CRUD"、{R} → "R"、空 → "" */
    public static String opsLabel(Set<CrudClassifier.CrudOp> ops) {
        if (ops == null || ops.isEmpty()) return "";
        StringBuilder sb = new StringBuilder();
        for (var op : ORDER) {
            if (ops.contains(op)) sb.append(op.name());
        }
        return sb.toString();
    }
}

Markdownテーブル出力

Java — Markdownテーブル生成
public String toMarkdown(CrudMatrixAggregator aggregator) {
    var matrix = aggregator.getMatrix();
    var tables = aggregator.getAllTables();

    StringBuilder sb = new StringBuilder();

    // ヘッダー行
    sb.append("| クラス");
    tables.forEach(t -> sb.append(" | ").append(t));
    sb.append(" |\n");

    // セパレーター行
    sb.append("|---");
    tables.forEach(t -> sb.append("|:---:"));
    sb.append("|\n");

    // データ行
    matrix.forEach((cls, row) -> {
        // クラス名は短縮(最後のセグメントのみ)
        String shortName = cls.contains(".") ?
            cls.substring(cls.lastIndexOf('.') + 1) : cls;
        sb.append("| ").append(shortName);
        tables.forEach(table -> {
            Set<CrudClassifier.CrudOp> ops = row.getOrDefault(table, Set.of());
            sb.append(" | ").append(opsLabel(ops));
        });
        sb.append(" |\n");
    });

    return sb.toString();
}
Markdownテーブル 出力例
| クラス              | order_items | orders | users |
|---------------------|:-----------:|:------:|:-----:|
| OrderRepository     | CRD         | CRU    |       |
| ReportService       | R           | R      | R     |
| UserRepository      |             |        | CRU   |

Mermaid出力

Mermaid の xychart-betablock では行列表現が難しいため、 ここでは操作を エッジ として表現する有向グラフ(flowchart LR)を生成します。 GitHub の Markdown・Notion・Confluence で直接レンダリングされます。

Java — Mermaid flowchart LR 生成
public String toMermaid(CrudMatrixAggregator aggregator) {
    var matrix = aggregator.getMatrix();
    StringBuilder sb = new StringBuilder("flowchart LR\n");

    matrix.forEach((cls, row) -> {
        String clsId = sanitize(cls);
        sb.append("  ").append(clsId)
          .append("[\"").append(shortName(cls)).append("\"]\n");

        row.forEach((table, ops) -> {
            String tableId = sanitize(table);
            sb.append("  ").append(tableId)
              .append("[(").append(table).append(")]\n");
            sb.append("  ").append(clsId)
              .append(" --").append(opsLabel(ops)).append("--> ")
              .append(tableId).append("\n");
        });
    });
    return sb.toString();
}

private String sanitize(String s) {
    return s.replaceAll("[^a-zA-Z0-9_]", "_");
}

private String shortName(String fqcn) {
    return fqcn.contains(".") ? fqcn.substring(fqcn.lastIndexOf('.') + 1) : fqcn;
}
Mermaid 出力例(```mermaid ブロックに貼り付ける)
flowchart LR
  OrderRepository["OrderRepository"]
  order_items[(order_items)]
  OrderRepository --CRD--> order_items
  orders[(orders)]
  OrderRepository --CRU--> orders
  ReportService["ReportService"]
  order_items[(order_items)]
  ReportService --R--> order_items

PlantUML出力

PlantUML は rectangledatabase を使ってCRUD図を表現します。 Jenkins や Confluence の PlantUML プラグインで利用できます。

Java — PlantUML 生成
public String toPlantUml(CrudMatrixAggregator aggregator) {
    var matrix = aggregator.getMatrix();
    var tables = aggregator.getAllTables();
    StringBuilder sb = new StringBuilder("@startuml\nleft to right direction\n\n");

    // テーブルノード
    tables.forEach(t ->
        sb.append("database \"").append(t).append("\" as ").append(t).append("\n")
    );
    sb.append("\n");

    // クラスノード+矢印
    matrix.forEach((cls, row) -> {
        String s = shortName(cls);
        sb.append("rectangle \"").append(s).append("\" as ").append(s).append(" {\n}\n");
        row.forEach((table, ops) ->
            sb.append(s).append(" --> ").append(table)
              .append(" : ").append(opsLabel(ops)).append("\n")
        );
    });
    sb.append("@enduml\n");
    return sb.toString();
}

ファイル書き出し

Java — 出力ファイルへの書き込み
import java.nio.file.*;
import java.nio.charset.StandardCharsets;

CrudMatrixBuilder builder = new CrudMatrixBuilder();
CrudMatrixAggregator agg   = builder.build(Path.of("src/main/java"));
CrudRenderer renderer      = new CrudRenderer();

// Markdown
Files.writeString(Path.of("crud-matrix.md"),
    renderer.toMarkdown(agg), StandardCharsets.UTF_8);

// Mermaid
Files.writeString(Path.of("crud-diagram.mmd"),
    renderer.toMermaid(agg),  StandardCharsets.UTF_8);

// PlantUML
Files.writeString(Path.of("crud-diagram.puml"),
    renderer.toPlantUml(agg), StandardCharsets.UTF_8);

System.out.println("CRUD図を出力しました。");

💡 GitHubでの表示

.md ファイルに ```mermaid ブロックとして埋め込めば、GitHub の README や Pull Request で自動レンダリングされます。CI で毎回更新してコミットすることで、常に最新のCRUD図を維持できます。

次の章では…

PART 07 ではここまで実装したコードを実際のサンプルプロジェクトで動かし、出力されたCRUD図を確認します。

→ PART 07 — 動作デモへ