カテゴリ: Spring 更新日: 2026/01/07

Springの@Repositoryアノテーションの使い方を徹底解説!初心者でもわかるSpringフレームワークのデータアクセス

Springの@Repositoryアノテーション
Springの@Repositoryアノテーション

先生と生徒の会話形式で理解しよう

生徒

「Springフレームワークで@Repositoryアノテーションを見かけたんですが、これは何をするものなんですか?」

先生

@Repositoryはデータアクセス層のクラスに付けるアノテーションだよ。例えば、データベースに接続して情報を取得したり、保存したりする役割を持つんだ。」

生徒

「なるほど、@Service@Componentとどう違うんですか?」

先生

「いい質問だね。@Serviceはビジネスロジックを、@Componentは汎用的なBeanを表すけど、@Repositoryは特にデータアクセスのために使われるんだ。では、具体的な使い方を見ていこう!」

1. @Repositoryアノテーションとは?

1. @Repositoryアノテーションとは?
1. @Repositoryアノテーションとは?

@Repositoryアノテーションは、Springフレームワークの一部で、データアクセス層(DAO)のクラスに使用します。これにより、Springが例外をデータアクセス関連の例外に変換してくれるため、例外処理が簡単になります。

例えば、以下のようにデータベース操作を行うクラスに@Repositoryを付けます。


import org.springframework.stereotype.Repository;
import org.springframework.data.jpa.repository.JpaRepository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);
}

このUserRepositoryインターフェースは、Spring Data JPAによって自動的に実装され、データベース操作が可能になります。

2. @Repositoryの主な機能とメリット

2. @Repositoryの主な機能とメリット
2. @Repositoryの主な機能とメリット
  • データベース接続の管理: @Repositoryを付けたクラスは、データベース接続をSpringが自動的に管理してくれます。
  • 例外処理の簡略化: データアクセス例外がDataAccessExceptionに変換されるため、統一された例外処理が可能です。
  • CRUD操作の簡素化: JpaRepositoryを継承することで、savefindAlldeleteなどの基本的なデータ操作が簡単に行えます。

3. @Repositoryと@Queryの組み合わせ

3. @Repositoryと@Queryの組み合わせ
3. @Repositoryと@Queryの組み合わせ

デフォルトのCRUD操作に加えて、@Queryアノテーションを使うことで、カスタムなSQLクエリも定義できます。


import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {

    @Query("SELECT p FROM Product p WHERE p.price > :price")
    List<Product> findProductsByMinPrice(@Param("price") double price);
}

この例では、価格が指定された値以上の商品を検索するクエリを作成しています。

Spring FrameworkやThymeleafを使った Webアプリ開発の全体像をやさしく理解したい人には、 この入門書が定番です。

Spring Framework超入門をAmazonで見る

※ Amazon広告リンク

4. @Repositoryの注意点

4. @Repositoryの注意点
4. @Repositoryの注意点

デフォルトでは@RepositoryのBeanはSingletonとして管理されます。そのため、状態を持つフィールドを使用するとスレッドセーフではなくなる可能性があります。もし状態を持つ必要がある場合は、@Scope("prototype")を使用しましょう。


import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;

@Repository
@Scope("prototype")
public class PrototypeRepository {
    // インスタンスごとに異なる状態を持てます
}

5. @Repositoryの活用方法

5. @Repositoryの活用方法
5. @Repositoryの活用方法

実際に@Repositoryを活用して、データベース操作を行う例を見てみましょう。


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/user")
    public String getUser() {
        return userRepository.findByUsername("john").toString();
    }
}

実行結果例


GET /user
=> User{id=1, username='john', email='john@example.com'}

6. @Repositoryと例外変換(Exception Translation)の仕組み

6. @Repositoryと例外変換(Exception Translation)の仕組み
6. @Repositoryと例外変換(Exception Translation)の仕組み

@Repositoryを付ける最大のメリットは、JPAやJDBC由来の例外をSpringの統一例外(DataAccessException階層)に自動変換してくれる点です。これにより、データベースごとの差異に依存しない一貫したエラーハンドリングが可能になり、アプリ全体の保守性と可読性が向上します。

Spring Data JPA のリポジトリはフレームワーク側で例外変換が適用されるため、明示的な@Repositoryがなくても同等に動作しますが、DAO/リポジトリ層であることを示すアノテーションとして付与しておくと、役割の明確化に有効です。


import org.springframework.dao.DataAccessException;

public class UserFacade {

    private final UserRepository userRepository;

    public UserFacade(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void safeSave(User user) {
        try {
            userRepository.save(user); // ここで発生した例外は DataAccessException に変換
        } catch (DataAccessException ex) {
            // ログ出力やドメイン例外への再変換など、統一的に処理
            throw new RuntimeException("データアクセスエラーが発生しました。", ex);
        }
    }
}

7. @Repositoryと@Transactionalの連携:トランザクション境界のベストプラクティス

7. @Repositoryと@Transactionalの連携:トランザクション境界のベストプラクティス
7. @Repositoryと@Transactionalの連携:トランザクション境界のベストプラクティス

トランザクションは通常、@Service層に@Transactionalを付与して「ユースケース単位」で管理するのが定石です。@Repositoryはデータアクセスに専念させ、書き込み系は @Transactional(デフォルト)、読み取り系は readOnly=trueで明示します。これにより、Springフレームワークのデータアクセス最適化(フラッシュ戦略やキャッシュ利用)が効き、性能と整合性が両立します。


import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional(readOnly = true)
    public User loadUser(String username) {
        return userRepository.findByUsername(username);
    }

    @Transactional
    public User register(User user) {
        // 複数のRepositoryをまたぐ操作も1トランザクションで安全に実行
        return userRepository.save(user);
    }
}

8. Spring Data JPAのメソッド名クエリ/Pageable・Sortの活用

8. Spring Data JPAのメソッド名クエリ/Pageable・Sortの活用
8. Spring Data JPAのメソッド名クエリ/Pageable・Sortの活用

@RepositoryとSpring Data JPAを組み合わせると、メソッド名からクエリを自動生成できます。さらにPageableSortを使えば、一覧画面向けのページング・並び替えを少ないコードで実装可能です。


import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Repository;
import org.springframework.data.jpa.repository.JpaRepository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    // メソッド名クエリ:部分一致 + 降順
    List<User> findByUsernameContainingOrderByCreatedAtDesc(String keyword);

    // ページング対応:ステータスで絞り込み
    Page<User> findByStatus(UserStatus status, Pageable pageable);

    // ソートだけ渡すバリエーション
    List<User> findAll(Sort sort);
}

複雑な条件は@QuerySpecification(JPA Criteria)で拡張できます。DTO投影や@EntityGraphでN+1問題を回避するのも有効です。

9. @Repositoryのテスト戦略:@DataJpaTestで高速&信頼性の高い検証

9. @Repositoryのテスト戦略:@DataJpaTestで高速&信頼性の高い検証
9. @Repositoryのテスト戦略:@DataJpaTestで高速&信頼性の高い検証

リポジトリの単体テストには@DataJpaTestが適しています。組み込みデータベース(H2など)を利用し、エンティティマッピングやクエリ生成、例外変換の挙動を素早く検証できます。


import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;

import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
class UserRepositoryTest {

    @Autowired
    UserRepository userRepository;

    @Test
    void findByUsername_returnsEntity() {
        User saved = userRepository.save(new User("john", "john@example.com"));
        User found = userRepository.findByUsername("john");
        assertThat(found.getId()).isNotNull();
        assertThat(found.getEmail()).isEqualTo("john@example.com");
    }
}
  • ベストプラクティス: テストデータはBuilderやFixtureで再利用し、実データに近い制約(ユニークキー等)を付与する。
  • 注意点: フェッチ戦略(LAZY/EAGER)や@Transactionalの境界に依存するテストは、サービス層の統合テストでも補完する。

まとめ

まとめ
まとめ

今回の記事では、JavaのSpringフレームワークにおける@Repositoryアノテーションについて詳しく解説しました。@Repositoryは、データアクセス層で使用されるアノテーションであり、データベース操作を行う際に非常に便利です。このアノテーションを使用することで、データベース接続の管理や例外処理が簡略化され、コードの可読性が向上します。また、JpaRepositoryインターフェースを継承することで、標準的なCRUD操作を短いコードで実装できる点も大きな魅力です。

特に、@Queryアノテーションと組み合わせることで、複雑なデータ検索やカスタムクエリの作成が可能になるため、柔軟なデータアクセスが実現できます。@Repositoryを理解し、適切に活用することで、Springを使ったアプリケーション開発がよりスムーズになるでしょう。また、@Scope("prototype")の設定によって、デフォルトのSingleton管理から脱却し、必要に応じたBeanのスコープ設定もできることを押さえておくと、より高度なアプリケーション設計が可能です。

最後に、データアクセス層の設計はアプリケーション全体のパフォーマンスに大きな影響を与えるため、@Repositoryの効果的な活用方法を学ぶことは非常に重要です。データベースの操作やアクセスの最適化は、エンタープライズシステムにおいて重要な役割を果たします。この知識をベースに、今後の開発に役立ててください。

サンプルコードの振り返り

最後に、もう一度@Repositoryを活用した基本的な例をおさらいしてみましょう。


import org.springframework.stereotype.Repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {

    // カスタムクエリで特定の名前の顧客を検索
    @Query("SELECT c FROM Customer c WHERE c.name = :name")
    Customer findByName(@Param("name") String name);
}

この例では、CustomerRepositoryインターフェースを使って、特定の顧客名に基づいた検索を実装しています。このように、@Repository@Queryを活用することで、柔軟で効率的なデータ操作が可能です。

先生と生徒の振り返り会話

生徒

「今日学んだ@Repositoryアノテーション、すごく便利ですね!特に、JpaRepositoryを使うだけで基本的なCRUDができるのは驚きました。」

先生

「その通りだね。データベース操作をシンプルにするためにSpringが用意している仕組みだから、ぜひ活用してみてほしい。覚えておくと、データアクセスのコードがすごく短く、効率的に書けるよ。」

生徒

@Queryを使って独自のクエリを書けるのも便利だと思いました。もっと複雑な検索条件も設定できそうですね。」

先生

「その通り。必要に応じてカスタムクエリを追加して、柔軟に対応できるのが@Repositoryの強みなんだ。次は、@Transactionalアノテーションについて学んで、データ操作時のトランザクション管理もマスターしていこう!」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Springフレームワークの@Repositoryアノテーションとは何ですか?役割や意味、DAOとの関係、データアクセスで何をしてくれるのかを基礎から知りたいです。

Repositoryはデータアクセス層を示すアノテーションで、Spring Data JPAやJDBCなどのデータベースアクセスを担うクラス/インターフェースに付けます。役割は「データ取得・保存・更新・削除(CRUD)」の窓口を明確化し、例外をDataAccessExceptionへ変換するなど、Springフレームワーク標準のデータアクセス指針に沿った実装を楽にする点にあります。

@Repositoryと@Serviceの違いは何ですか?ビジネスロジックとデータアクセスの責務分離、使い分けの考え方を教えてください。

Serviceはユースケースやビジネスルールをまとめる層、Repositoryはエンティティの永続化や検索などデータアクセスに特化した層です。役割を分けることでコードの見通しが良くなり、Springフレームワークの依存関係管理やテストの単純化、変更の影響範囲の局所化がしやすくなります。

@Repositoryと@ComponentはどちらもSpringのBeanですが、アノテーションの意味や使いどころの違いはありますか?

Componentは汎用的なBeanを示す広い概念で、Repositoryはデータアクセス専用の役割名です。Repositoryを付けると例外変換などデータアクセス特有の扱いが受けられ、プロジェクト内で層(レイヤ)の責務が明確になります。

命名クエリでの部分一致や範囲検索はどこまで表現できますか?

Containing、Between、LessThan、GreaterThan、Inなどの語彙で多くの条件を記述できます。限界を感じたら@Queryへ切り替えましょう。

@DataJpaTestは何をしてくれますか?Repositoryのテストで使うメリットを知りたいです。

JPA関連のコンポーネントだけを起動し、組み込みデータベースで素早く検証できます。エンティティのマッピングやクエリ生成の確認、例外の発生条件などを短時間でテストできます。

実データベースを使わずに信頼できるテストは可能ですか?

多くのケースは組み込みDBで十分検証できます。製品依存の挙動やパフォーマンスを確認したい場合のみ本番同等の環境での統合テストを追加します。

テストデータの用意はどうするのが良いですか?

BuilderやFixtureを用意して再利用可能な初期化コードを整えます。一意制約や長さ制約など本番に近い条件でデータを作り、現実的な検証を行います。

リポジトリのテストでは何を重点的に確認すべきですか?

保存・更新・削除・検索の基本、メソッド名クエリや@Queryの動作、境界条件(存在しないIDや空結果)を確認します。戻り値のNullやOptionalの扱いも重要です。

テストのトランザクションはどう扱われますか?

多くの場合テストはトランザクション内で実行され、メソッド終了時にロールバックされます。副作用を残さずに繰り返し実行でき、安定したテストが可能です。

フェッチ戦略やN+1問題はテストで検出できますか?

適切なサンプルデータを用意し、アクセス回数やSQLログを観察すれば兆候を捉えられます。必要に応じてEntityGraphやフェッチタイプの見直しを行います。
カテゴリの一覧へ
新着記事
Spring Frameworkでセッション管理をする!@SessionScopeの使い方を覚えよう!
JSPで改行やスペースを正しく表示する方法!HTMLとの連携ポイントも解説
JavaのExceptionクラスを完全解説!初心者でも理解できる例外処理の基本
Thymeleafのth:eachの使い方!ループ回数やindexなどの繰り返し処理を学ぼう
人気記事
No.1
Java&Spring記事人気No1
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.2
Java&Spring記事人気No2
Springの@Serviceアノテーションの使い方を徹底解説!初心者でもわかるSpring フレームワーク入門
No.3
Java&Spring記事人気No3
Thymeleafのth:classappend属性の使い方を完全ガイド!初心者でもわかる動的クラス追加
No.4
Java&Spring記事人気No4
Spring Data JPA入門!findAll()やfindBy**()の使い方などデータベース操作の基礎を学ぶ
No.5
Java&Spring記事人気No5
Spring BootのJakarta移行ガイド!初心者向けjavax→jakarta変更ポイント徹底解説
No.6
Java&Spring記事人気No6
Thymeleaf(タイムリーフ)入門!初心者でもわかるSpring Bootとテンプレートエンジンの使い方
No.7
Java&Spring記事人気No7
Springの@Repositoryアノテーションの使い方を徹底解説!初心者でもわかるSpringフレームワークのデータアクセス
No.8
Java&Spring記事人気No8
JavaのEnumクラスのordinalメソッドを徹底解説!初心者でもわかる列挙型の順序番号

💻 作業効率アップに

長時間のコーディングでも疲れにくい♪ 静音ワイヤレスマウス

Logicool Signature M750 を見る

※ Amazon広告リンク