1. test 1
  2. test 2
  3. test 3
  4. test 4
  5. test 5
  6. test 6
  7. test 7
コース一覧
Spring Boot入門
メソッド名からクエリを作る

Spring Boot入門

Java で Web API サーバーを作るための Spring Boot の入門コースです。DI コンテナ、REST コントローラ、リクエスト検証、レイヤ分割、Spring Data JPA、例外ハンドリング、テストまでを扱います。毎レッスン、Spring が裏側でやっている判断そのものを pure Java の関数として自分で書き、フレームワークが何を肩代わりしてくれているのかを手触りで理解できる構成にしました。約 12 時間 (1 日 30 分 × 24 日) で 48 レッスンを修了できます。

1
Spring Bootとは何か
01. Spring Bootで何が作れるのか10分
02. サーブレットからフレームワークへ15分
03. ルーティング表という発想15分
04. プロジェクトの構成10分
05. 起動のしくみと自動設定15分
06. パスのマッチング15分
2
DIコンテナ
01. newで書くと何が困るのか15分
02. コンストラクタインジェクション15分
03. インターフェースへの依存15分
04. @Componentと@Bean15分
05. 自作のDIコンテナ20分
06. Beanのスコープとライフサイクル15分
3
RESTコントローラ
01. RESTという設計方針15分
02. @RestControllerの役割15分
03. @GetMappingとパス変数15分
04. クエリパラメータの受け取り15分
05. @PostMappingとリクエストボディ15分
06. ステータスコードの選び方15分
07. ResponseEntityで組み立てる15分
4
リクエストとレスポンスの変換
01. JSONとオブジェクトの往復15分
02. DTOとエンティティを分ける15分
03. recordでDTOを書く15分
04. 入力検証の基本15分
05. 検証エラーをまとめて返す15分
06. アノテーションによる検証15分
5
レイヤ構成とビジネスロジック
01. 3層アーキテクチャ10分
02. @Serviceに置くもの15分
03. 状態遷移をルールにする15分
04. 料金計算のような業務ロジック15分
05. @Transactionalとは何か15分
06. トランザクションの巻き戻し15分
6
データアクセス
01. @Entityとテーブルの対応15分
02. リポジトリという抽象15分
03. メソッド名からクエリを作る20分
04. 検索条件の組み立て15分
05. ページングと並び替え15分
06. N+1問題15分
7
例外処理と横断的関心事
01. 例外をHTTPに変換する15分
02. @ExceptionHandlerと@ControllerAdvice15分
03. エラーレスポンスの形を決める15分
04. フィルタとインターセプタ15分
05. ログとリクエストの追跡15分
06. 設定値の外部化15分
8
テストと仕上げ
01. テストの種類と使い分け15分
02. Serviceの単体テスト15分
03. モックで依存を差し替える15分
04. MockMvcでエンドポイントを試す15分
05. 本番へ出すための次の一歩10分

メソッド名からクエリを作る

このレッスンでは、メソッド名からクエリが導き出される Spring Data JPA の規約を読み解き、同じ変換を自分の手で書けるようになります。

名前がそのまま仕様になります

リポジトリのインターフェースに、次のようなメソッドを1行足します。

Java

public interface UserRepository extends JpaRepository<User, Long> { List<User> findByNameAndAge(String name, int age); }

本体はありません。それでもこのメソッドを呼ぶと name と age の両方で絞り込んだ結果が返ります。Spring Data JPA は起動時にメソッド名を単語に分解し、そこからクエリを組み立てて実装を生成しているからです。この仕組みをクエリメソッド、あるいは導出クエリと呼びます。

名前が仕様そのものになるので、綴りを間違えると起動時に落ちます。エンティティに存在しないプロパティ名を書いた場合、実行してみるまで気づかないのではなく、アプリケーションが立ち上がらないという形で即座に分かります。これは欠点ではなく利点です。

名前の組み立て方

メソッド名は、先頭の動詞、By、そして条件の並びという構造をしています。

部品意味例
findBy / readBy / getBy検索するfindByName
countBy件数を数えるcountByAge
existsBy存在を確かめるexistsByEmail
deleteBy削除するdeleteByName
And / Or条件をつなぐfindByNameAndAge
OrderBy + プロパティ + Asc / Desc並び替えるfindByAgeOrderByNameAsc

条件そのものにも修飾が付けられます。よく使うものを挙げます。

書き方生成される条件
findByNamename = ?
findByNameContainingname LIKE %?%
findByNameStartingWithname LIKE ?%
findByAgeGreaterThanage > ?
findByAgeLessThanage < ?
findByAgeBetweenage BETWEEN ? AND ?
findByNameIsNullname IS NULL
findByNameNotname <> ?

プロパティ名はキャメルケースで書き、先頭を小文字に戻したものがそのまま列に対応します。findByUserName なら userName プロパティを見に行きます。

この表は Spring Data JPA が実際に解釈できる語彙です。ただし今回の演習で自分の手で書くのは、このうち等値の条件を And と Or でつないだ形だけです。Containing や GreaterThan まで自分で実装しようとすると、それだけで演習が終わってしまうためです。残りは Spring がやってくれる範囲として、表で見て知っておけば十分です。

便利さの限界も知っておきます

条件が2つ3つのうちは読みやすい仕組みですが、増えるとメソッド名が壊滅的に長くなります。

Java

List<User> findByNameContainingAndAgeGreaterThanAndActiveTrueOrderByCreatedAtDesc( String name, int age);

こうなったら @Query で JPQL を直接書くか、後のレッスンで扱う動的な組み立てに切り替える合図です。目安として、条件が3つを超えたあたりから名前で表現するのをやめるとよいでしょう。

演習で書くもの

演習では、Spring Data JPA が起動時にやっている変換そのものを書きます。findByNameAndAge のようなメソッド名を文字列で受け取り、対応する SQL 相当の文字列を組み立てて返します。実装する規則は次の表の通りです。テーブル名は常に users とします。

入力出力
findAllSELECT * FROM users
findByNameSELECT * FROM users WHERE name = ?
findByNameAndAgeSELECT * FROM users WHERE name = ? AND age = ?
findByNameOrEmailSELECT * FROM users WHERE name = ? OR email = ?
findByNameAndAgeAndEmailSELECT * FROM users WHERE name = ? AND age = ? AND email = ?

規則をまとめます。先頭の findBy を取り除いた残りを、区切り語 And と Or で分割します。分割して得られた各プロパティ名は先頭を小文字にして列名とし、列名 = ? の形にします。区切り語 And は SQL では AND、Or は OR として、元の並び順のまま条件の間に挟みます。入力が findAll のときだけ WHERE 句を付けません。入力が findBy で始まらない場合は UNSUPPORTED を返してください。

区切り語は大文字で始まる単語として現れるので、And と Or の位置を文字列として探せば分割できます。プロパティ名の途中に And を含む語は今回は考えなくてかまいません。

要件

  1. findAll のときは SELECT * FROM users を返すこと
  2. findBy で始まるときは条件を And と Or で分割し、列名 = ? を AND と OR でつないだ WHERE 句を組み立てること
  3. プロパティ名の先頭は小文字に変換すること。findAll でも findBy 始まりでもない場合は UNSUPPORTED を返すこと

入出力例

toSql("findAll") → "SELECT * FROM users" toSql("findByName") → "SELECT * FROM users WHERE name = ?" toSql("findByNameAndAge") → "SELECT * FROM users WHERE name = ? AND age = ?" toSql("findByNameOrEmail") → "SELECT * FROM users WHERE name = ? OR email = ?" toSql("findByNameAndAgeAndEmail") → "SELECT * FROM users WHERE name = ? AND age = ? AND email = ?" toSql("findByUserNameAndAge") → "SELECT * FROM users WHERE userName = ? AND age = ?" toSql("saveAll") → "UNSUPPORTED"

ヒント

先に methodName.equals("findAll") と methodName.startsWith("findBy") を判定してから、substring(6) で残りを取り出します

残りの文字列を1文字ずつ走査し、位置 i から And または Or で始まっていて、かつその直後がまた大文字なら区切りだと判断できます。startsWith("And", i) が使えます

列名は Character.toLowerCase(s.charAt(0)) + s.substring(1) で作れます。条件と接続語を交互に StringBuilder へ足していきます

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/08/09

関連レッスン

  • 検索条件の組み立て

    指定された条件だけを WHERE 句に足す処理を実装します。

  • ページングと並び替え

    ページ番号と件数から取り出す範囲を計算します。

  • N+1問題

    発行されるクエリ本数を数え、N+1 を検出できるようになります。

  • 例外をHTTPに変換する

    例外の種類からステータスコードを決める処理を実装します。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • メソッドクラスに属する関数
  • リポジトリプロジェクトの保管場所
  • インターフェースインターフェースはメソッドの宣言のみ(実装なし)、複数実装可能。
  • エンティティDB の 1 行 = アプリの 1 オブジェクト
  • プロパティメソッドを属性のようにアクセスできるようにするデコレータ。
  • キャメルケースmyProject 形式。JS 変数向け
  • SQLデータベースを操作するための共通言語
  • テーブルDB の表 (Excel のシートみたいなもの)
main.java
学習モード
エディタを読み込んでいます

メモ

メソッド名からクエリを作る

⌘S で保存