クラスが何百個も並び、上から読んでいるうちに何を調べていたか分からなくなる。そんなときは「問い合わせ一覧を開く」のように、一つの操作から読み始めます。
先に結論
- 調べる操作と、読み終える条件を決める。最初からすべてのクラスを理解しようとしない。
- 画面→HTTP→Controller→Service→DBを追う。戻り値が画面へ届く経路も確認する。
- 入口・入力・出力・未確認を一枚に残す。読んだことと、実行して確かめたことを分ける。
この記事では架空の問い合わせ管理を使い、一つの機能の経路と調査メモの作り方を示します。
まず、調べる動作を一つに絞る
題材には件名、投稿者、担当者と、下書き・受付済み・対応中・完了の状態があります。件名は必須で1〜100文字。今回は登録や更新には広げず、受付済みの問い合わせだけを一覧表示する動作に絞ります。
読み終える条件は「リクエスト、呼ばれるメソッド、検索条件、返す項目、0件時の結果を説明できる」です。認証やページ送りも今回の表示に関わる部分は確認し、残りを未確認欄に置きます。
調査範囲を絞っても、アクセス制御など結果を変える条件は無視しません。実案件ではREADME、起動方法、使用する版、テストの入口を読み、動かすデータが開発用であることを確認します。
起動できない場合も、静的に読んだ範囲と実行した範囲を分けたまま調査できます。
画面からDB、戻り値までを一本で追う

Controllerから先へ降りるだけでなく、戻り値が画面へ着くまでを追います。今回の経路は次のとおりです。
問い合わせ一覧の「受付済み」を選ぶ
→ GET /api/inquiries?status=受付済み
→ InquiryController.list(status)
→ InquiryService.list(status)
→ InquiryRepository.findByStatus(status)
→ DB: inquiriesをstatusで検索
→ List<Inquiry> → JSON応答 → 一覧の行を表示
この例の検証範囲
Java 17.0.8、Spring Framework 6.1.1のMockMvc、H2 2.2.224で、リクエストの振り分け→DB検索→JSON応答を確認しました。
図は説明用の構成です。この版は再現環境であり、現在の推奨版ではありません。ブラウザ描画・実ネットワーク・認証・登録機能は未検証です。
1. 画面で起きた通信を入口にする
「受付済み」を選んだとき、画面のURLが変わるのか、裏でAPIを呼ぶのかを見ます。開発者向け機能で調べられる環境なら、操作直前に記録を始め、パス・HTTPメソッド・パラメーター・応答を確認します。
この例はGET /api/inquiries、条件はstatus=受付済みです。文言が翻訳ファイルや共通部品にあって探しづらい場合も、観測したパスがコードの入口を探す手がかりになります。
通信が発生しなければ、取得済みのデータを画面内で絞っている可能性があります。「通信なし=DBは無関係」とはせず、元のデータを取得した通信へ一つ戻ります。
共有する前に確認
認証ヘッダーやCookieを、そのまま共有資料に貼らないでください。
2. Controllerの入力と呼び出し先を読む
Spring MVCでは、クラスの@RequestMappingとメソッドの@GetMappingなどを合わせて読みます。URLだけでなくHTTPメソッド等も対応条件です。Spring公式のリクエストマッピングで仕組みを確認できます。
以下は検証用コードの断片です。クラス全体や必要なimportは省略しています。
@GetMapping("/api/inquiries")
public List<Inquiry> list(@RequestParam("status") String status)
throws SQLException {
return service.list(status);
}
見るのは「どこから来るか」「何を受け取るか」「何を呼ぶか」「何を返すか」です。この断片ではstatusを受け取り、そのままServiceへ渡します。
入力の妥当性、ログイン利用者、権限のチェックはこの断片からは分かりません。実案件では別の設定や処理を確認し、メソッドが短いことだけで調査を終えないようにします。
役割を整理したくなったら、Controllerでやってはいけないことへ進めます。経路を読んでいる最中に、設計の修正まで始める必要はありません。
3. Serviceから検索条件とDBを追う
この例のServiceは、RepositoryのfindByStatusへstatusを渡すだけです。実案件では所属で検索範囲を狭めたり、値を変換したりするため、引数名が同じでも途中の値を追います。
次も実装から抜き出したSQLの断片です。
SELECT id, title, status
FROM inquiries
WHERE status = ?
ORDER BY id
?にはJava側からstatusを設定します。JDBCのPreparedStatementは、パラメーターへ値を設定して実行する仕組みです。この例は文字列をSQLへ連結しません。
テーブル名だけでなく、画面の「受付済み」がWHERE句へ届くか、並び順は何か、どの列を返すかを対応づけます。
ORMでSQLがソースにない場合は、Repositoryの定義やマッピングを調べ、必要に応じて開発環境のSQL記録で補います。ログに出ないことだけで、SQL未実行とは断定できません。
4. DBの結果が画面へ戻るまでを見る
DBの1行をどのオブジェクトへ変換し、Serviceがどう加工し、Controllerが何を返すかを逆に追います。APIと画面で名前が違う項目や、一覧に出していない列にも目を向けます。
今回のテストでは、受付済みはID 1と3の2件で、次のJSONを返しました。完了は0件なので、応答は空配列[]でした。
[
{"id":1,"title":"ログイン方法","status":"受付済み"},
{"id":3,"title":"設定相談","status":"受付済み"}
]
Spring公式の説明のとおり、MockMvcは実HTTPサーバーを動かさずSpring MVCの処理を試します。JSONが正しくても「ブラウザで0件メッセージが表示された」とは言えません。
画面側の配列の描画、0件表示、通信失敗時の表示を別に追います。
調査メモには、経路と未確認を残す
次の担当者が追い直せるように、今回の確認結果を短くまとめます。
記入例|問い合わせ一覧の調査メモ
- 対象動作:受付済みの問い合わせ一覧。
- 入口・入力:GET
/api/inquiries、statusは受付済み。 - 処理:Controller.list → Service.list → Repository.findByStatus。
- データ:inquiriesのstatus一致。id昇順でid/title/statusを取得。
- 確認結果:MockMvc+H2で200・2件。完了を指定すると200・空配列。
- 未確認:ブラウザ描画、認証、実DB差、ページ送り、登録処理。
実案件では、確認したブランチやコミット、ファイルとメソッド、実行条件も添えます。「たぶんこの処理」なら仮説と書き、呼び出された証拠がある場所と分けます。
コメントには変更前の仕様が残ることもあるため、コメントの書き方も意識しつつ実装と照合します。
一本つながったら「担当者で絞るとどこが変わるか」へ広げられます。Serviceが大きく読みづらいときは、Serviceの分割例が判断を補います。
読み終える前のチェック
- 調べる操作と、読み終える条件を決めたか。
- 画面・HTTP・Controller・Service・DBの入力と出力がつながったか。
- 取得条件、返す項目、0件時の結果を確認したか。
- 戻り値の確認と、実際の画面の確認を区別したか。
- 観測した事実、仮説、未確認を調査メモに残したか。
